libFAUDES

Sections

Index

hio_functions.cpp

Go to the documentation of this file.
00001 /** @file hio_functions.cpp Algorithms for hierarchical discrete event systems with inputs and outputs */
00002 
00003 /* Hierarchical IO Systems Plug-In for FAU Discrete Event Systems Library (libfaudes)
00004 
00005    Copyright (C) 2006  Sebastian Perk 
00006    Copyright (C) 2006  Thomas Moor 
00007    Copyright (C) 2006  Klaus Schmidt
00008 
00009 */
00010 
00011 // note: deterministic generators only 
00012 
00013 // todo: exceptions on invalid input data if FAUDES_CHECKED
00014 // todo: files eg: normal. cycles. hiotest. hiosynth.
00015 // todo: implement routines that check hio properties
00016 // todo: only use statenames if statenamesenabled (eg HioFreeInput)
00017 
00018 // todo: other todos below
00019 
00020 #include "hio_functions.h"
00021 #include "syn_include.h"
00022 
00023 
00024 namespace faudes {
00025 
00026 // CompleteSynth(rPlant,rCAlph,rSpec,rClosedLoop)
00027 bool CompleteSynth(
00028   const Generator& rPlant,
00029   const EventSet rCAlph, 
00030   const Generator& rSpec, 
00031   Generator& rClosedLoop) { 
00032   FD_DF("CompleteSynth(" << rPlant.Name() << "," << rSpec.Name()<< ")");
00033 
00034   // prepare result
00035   rClosedLoop.Clear();
00036   
00037   //check for trivial result
00038   if(rSpec.InitStatesEmpty()){
00039       FD_DF("CompleteSynth::empty language specification: empty closed loop.");
00040     rClosedLoop.Name("CompeleteSynth("+rPlant.Name()+", "+rSpec.Name()+")");
00041       return false; 
00042   }  
00043   
00044   // spec as candidate for closed loop
00045   Generator ClosedLoopCand=rSpec;
00046 
00047   // iterate supcon and dead end elimination
00048   while(true) {
00049     // try std synthesis
00050     FD_DF("CompleteSynth:: spec size " << ClosedLoopCand.Size());
00051     
00052     // try SupCon
00053     SupCon(rPlant, rCAlph, ClosedLoopCand, rClosedLoop);
00054     //std::cout<<std::endl<<"CompleteSynth:: current result after SupCon: tmp_ContLoop.gen";
00055     FD_DF("CompleteSynth: size of current result after SupCon: "<<rClosedLoop.Size());
00056     //std::cout<<" (Size: "<<rClosedLoop.Size()<<").";
00057     
00058     //check for empty result
00059     if(rClosedLoop.InitStatesEmpty()) {
00060       FD_DF("CompleteSynth:: failed: empty language result.");
00061       rClosedLoop.ClearStateNames();
00062       rClosedLoop.Name("CompeleteSynth("+rPlant.Name()+", "+rSpec.Name()+")");
00063       return false;
00064     }
00065       
00066     FD_DF("CompleteSynth:: candidate size " << rClosedLoop.Size());
00067     
00068     // find dead ends  and return success if no dead end found
00069     StateSet dead_ends=rClosedLoop.TerminalStates(rClosedLoop.AccessibleSet());
00070     if(dead_ends.Empty()) {
00071       rClosedLoop.ClearStateNames();
00072       FD_DF("CompleteSynth:: done");
00073       rClosedLoop.Name("CompeleteSynth("+rPlant.Name()+", "+rSpec.Name()+")");
00074       return true;
00075     }
00076     
00077     // report to console
00078     FD_DF("CompleteSynth:: eliminating following " << dead_ends.Size() << " dead ends");
00079     FD_DF(rClosedLoop.StateSetToString(dead_ends));
00080     
00081     // eliminate dead ends.
00082     rClosedLoop.DelStates(dead_ends);
00083     // becomes new candidate for SupCon
00084     ClosedLoopCand=rClosedLoop;
00085     
00086     //std::cout<<std::endl<<"CompleteSynth:: current result after Complete: tmp_CompleteLoop.gen";
00087     FD_DF("CompleteSynth:: size of result after removing dead ends: "<<rClosedLoop.Size());
00088     //std::cout<<" (Size: "<<rClosedLoop.Size()<<").";
00089 
00090     //check for empty result
00091     if(rClosedLoop.InitStatesEmpty()) {
00092       FD_DF("CompleteSynth:: failed: empty language result.");
00093       rClosedLoop.Name("CompeleteSynth("+rPlant.Name()+", "+rSpec.Name()+")");
00094       return false;
00095     }
00096     rClosedLoop.Clear();
00097   }
00098 }
00099 
00100 // NormalCompleteSynth(rPlant,rCAlph,rOAlph,rSpec,rClosedLoop)
00101 bool NormalCompleteSynth(
00102   Generator& rPlant, 
00103   const EventSet& rCAlph, 
00104   const EventSet& rOAlph,
00105   const Generator& rSpec,
00106   Generator& rClosedLoop) 
00107 { 
00108   FD_DF("NormalCompleteSynth(" << rPlant.Name() << "," << rSpec.Name()<< ")");
00109   
00110   // prepare result
00111   rClosedLoop.Clear();
00112   
00113   // spec as candidate for closed loop
00114   Generator Spec=rSpec;
00115   
00116   while(true) {
00117     
00118     // try CompleteSynth and check for empty result:
00119     if(!CompleteSynth(rPlant,rCAlph,Spec,rClosedLoop)) {
00120     FD_DF("NormalCompleteSynth:: failed: empty result after CompleteSynth().");
00121       std::cout<<std::endl<<"NormalCompleteSynth:: failed: empty result after CompleteSynth().";
00122     rClosedLoop.Name("NormalCompleteSynth(" + rPlant.Name() + "," + rSpec.Name()+ ")");
00123       return false;
00124     }
00125    
00126     // check for normality and return on success
00127     if(IsNormal(rPlant,rOAlph,rClosedLoop)) {
00128       FD_DF("NormalCompleteSynth:: candidate supervisor is normal. success.");
00129     rClosedLoop.Name("NormalCompleteSynth(" + rPlant.Name() + "," + rSpec.Name()+ ")");
00130       return true;
00131     }
00132     
00133     //  supremal normal sublanguage of rClosedLoop as new spec
00134     // return false on empty result
00135     FD_DF("NormalCompleteSynth:: candidate supervisor not normal. running SupNorm");
00136     if(!SupNorm(rPlant, rOAlph, rClosedLoop, Spec)) {
00137       FD_DF("NormalCompleteSynth:: failed: empty result after SupNorm().");
00138       std::cout<<std::endl<<"NormalCompleteSynth:: failed: empty result after SupNorm().";
00139     rClosedLoop.Clear();
00140     rClosedLoop.Name("NormalCompleteSynth(" + rPlant.Name() + "," + rSpec.Name()+ ")");
00141       return false;
00142     }  
00143     
00144     Spec.ClearStateNames();
00145     //std::cout<<std::endl<<"NormalCompleteSynth:: current result after SupNorm():";
00146     //std::cout<<" Size: "<<Spec.Size()<<".";
00147     FD_DF("NormalCompleteSynth:: size of result after SupNorm(): "<<Spec.Size());
00148   }
00149 }
00150 
00151 
00152 // NormalCompleteSynthNB(rPlant,rCAlph,rOAlph,rSpec,rClosedLoop)
00153 bool NormalCompleteSynthNB(
00154   Generator& rPlant, 
00155   const EventSet& rCAlph, 
00156   const EventSet& rOAlph,
00157   const Generator& rSpec,
00158   Generator& rClosedLoop) 
00159 { 
00160   FD_DF("NormalCompleteSynth(" << rPlant.Name() << "," << rSpec.Name()<< ")");
00161   
00162   // prepare result
00163   rClosedLoop.Clear();
00164 
00165   // spec as candidate for closed loop
00166   Generator Spec=rSpec;
00167   while(true) {
00168     
00169     // try NormalCompleteSynth and check for empty result:
00170     if(!NormalCompleteSynth(rPlant,rCAlph,rOAlph,Spec,rClosedLoop)) {
00171       FD_DF("NormalCompleteSynthNB:: failed: empty result after NormalCompleteSynth().");
00172       std::cout<<std::endl<<"NormalCompleteSynthNB:: failed: empty result after NormalCompleteSynth().";
00173     rClosedLoop.Name("NormalCompleteSynthNB(" + rPlant.Name() + "," + rSpec.Name()+ ")");
00174       return false;
00175     }
00176     
00177     // check for coaccessibility and return on success
00178     if(rClosedLoop.IsTrim()) {
00179       FD_DF("NormalCompleteSynthNB:: candidate supervisor is trim. success.");
00180     rClosedLoop.Name("NormalCompleteSynthNB(" + rPlant.Name() + "," + rSpec.Name()+ ")");
00181       return true;
00182     }
00183     
00184     // supremal nonblocking sublanguage of rClosedLoop as new Spec
00185     // return false on empty result
00186     FD_DF("NormalCompleteSynthNB:: candidate supervisor not Trim. running Trim()");
00187     Spec=rClosedLoop; 
00188     if(!Spec.Trim()) {
00189       FD_DF("NormalCompleteSynthNB:: failed: empty result after Trim().");
00190       std::cout<<std::endl<<"NormalCompleteSynthNB:: failed: empty result after Trim().";
00191       rClosedLoop.Clear(); 
00192       rClosedLoop.Name("NormalCompleteSynthNB(" + rPlant.Name() + "," + rSpec.Name()+ ")");
00193       return false;
00194       }
00195     //std::cout<<std::endl<<"NormalCompleteSynthNB:: current result after Trim():";
00196     //std::cout<<" Size: "<<Spec.Size()<<".";
00197     FD_DF("NormalCompleteSynthNB:: size of result after Trim():"<<Spec.Size());
00198     }
00199 }
00200 
00201 
00202 // HioSortCL(const EventSet& rYc,rUc,rYp,rUP,rYe,rUe)
00203 Generator HioSortCL(
00204   const EventSet& rYc, 
00205   const EventSet& rUc,
00206   const EventSet& rYp, 
00207   const EventSet& rUp,
00208   const EventSet& rYe,
00209   const EventSet& rUe)
00210 {
00211     FD_DF("HioSortCL(...)");
00212 
00213   #ifdef FAUDES_CHECKED
00214   // check for nonempty sets
00215   if (rYc.Empty()||rUc.Empty()||rYp.Empty()||rUp.Empty()||rYe.Empty()||rUe.Empty()){
00216       std::stringstream errstr;
00217       errstr << "At least one empty parameter.";
00218       throw Exception("HioSortCL", errstr.str(), 0);
00219   }
00220   #endif
00221   
00222   // create resulting alphabet while checking for disjoint sets
00223   EventSet alphabet,errevents;
00224   // initialize with rYc
00225   alphabet.SetUnion(rYc);
00226   // insert remaining events one by one and check if new
00227     EventSet::Iterator evit;
00228   // rUc
00229     for (evit = rUc.Begin(); evit != rUc.End(); ++evit) {
00230     if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
00231     }
00232   // rYp
00233     for (evit = rYp.Begin(); evit != rYp.End(); ++evit) {
00234     if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
00235     }
00236   // rUp
00237     for (evit = rUp.Begin(); evit != rUp.End(); ++evit) {
00238     if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
00239     }
00240   // rYe
00241     for (evit = rYe.Begin(); evit != rYe.End(); ++evit) {
00242     if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
00243     }
00244   // rUe
00245     for (evit = rUe.Begin(); evit != rUe.End(); ++evit) {
00246     if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
00247     }
00248   
00249   #ifdef FAUDES_CHECKED
00250   // throw exception on non disjoint alphabets
00251   if (!errevents.Empty()){
00252     std::stringstream errstr;
00253     errstr << "Non-disjoint parameters; ambiguous events:\n" <<errevents.ToString();
00254     throw Exception("HioSortCL", errstr.str(), 0);
00255   }
00256   #endif
00257   
00258   // create result
00259     Generator ResGen;
00260   
00261     ResGen.Name("HioSortCL("+rYc.Name()+","+rUc.Name()+","+rYp.Name()+","+rUp.Name()+","+rYe.Name()+","+rUe.Name()+")");
00262   
00263     ResGen.InjectAlphabet(alphabet);
00264   alphabet.Clear();
00265   
00266     // 5 marked states with initial state 1:
00267     ResGen.InsInitState("Yp_or_Ye");
00268     ResGen.SetMarkedState("Yp_or_Ye");
00269     ResGen.InsMarkedState("Yc_or_Up");
00270     ResGen.InsMarkedState("Uc");
00271     ResGen.InsMarkedState("Up");
00272     ResGen.InsMarkedState("Ue");
00273     
00274     // set transitions according to desired ioSorting structure:
00275     // all Yp-events lead from state 1 to state 2:
00276     for (evit = rYp.Begin(); evit != rYp.End(); ++evit) {
00277       ResGen.SetTransition("Yp_or_Ye",rYp.SymbolicName(*evit),"Yc_or_Up");
00278     }
00279     // all Yc-events lead from state 2 to state 3:
00280     for (evit = rYc.Begin(); evit != rYc.End(); ++evit) {
00281       ResGen.SetTransition("Yc_or_Up",rYc.SymbolicName(*evit),"Uc");
00282     }
00283     // all Uc-events lead from state 3 to state 4:
00284     for (evit = rUc.Begin(); evit != rUc.End(); ++evit) {
00285       ResGen.SetTransition("Uc",rUc.SymbolicName(*evit),"Up");
00286     }
00287     // all Up-events lead from state 2 and 4 to state 1:
00288     for (evit = rUp.Begin(); evit != rUp.End(); ++evit) {
00289       ResGen.SetTransition("Yc_or_Up",rUp.SymbolicName(*evit),"Yp_or_Ye");
00290       ResGen.SetTransition("Up",rUp.SymbolicName(*evit),"Yp_or_Ye");
00291     }
00292     // all Ye-events lead from state 1 to state 5:
00293     for (evit = rYe.Begin(); evit != rYe.End(); ++evit) {
00294       ResGen.SetTransition("Yp_or_Ye",rYe.SymbolicName(*evit),"Ue");
00295     }
00296     // all Ue-events lead from state 5 to state 1:
00297     for (evit = rUe.Begin(); evit != rUe.End(); ++evit) {
00298       ResGen.SetTransition("Ue",rUe.SymbolicName(*evit),"Yp_or_Ye");
00299     }
00300     return ResGen;
00301 } 
00302 
00303 // HioFreeInput(rGen,rInput,rOutput,rResGen,rErrState1,rErrState2,rErrState1Idx,rErrState2Idx) 
00304 void HioFreeInput(
00305   const Generator& rGen, 
00306   const EventSet& rInput, 
00307   const EventSet& rOutput,
00308   Generator& rResGen,
00309   const std::string& rErrState1, 
00310   const std::string& rErrState2,
00311   Idx& rErrState1Idx,
00312   Idx& rErrState2Idx) {
00313   FD_DF("HioFreeInput( [generator] " << rGen.Name() << ")");
00314 
00315   vGenerator* pResGen = &rResGen;
00316   if(&rResGen== &rGen) {
00317     pResGen= rResGen.New();
00318   }  
00319  
00320   #ifdef FAUDES_CHECKED
00321   // exception on empty Input-alphabet or non-disjoint Input and Output
00322   if(rInput.Empty() || !((rInput*rOutput).Empty())) {
00323       std::stringstream errstr;
00324       errstr << "Empty Input-alphabet or non-disjoint Input and Output.\n";
00325       errstr << "Input: "<< rInput.ToString()<<"\n";
00326       errstr << "Output: "<< rOutput.ToString()<<"\n";
00327       errstr << "Input*Output: "<< (rInput*rOutput).ToString()<<"\n";
00328       throw Exception("HioFreeInput", errstr.str(), 0); 
00329     }
00330   #endif
00331   
00332   // check for enabled state names:
00333   bool StateNamesEnabled = pResGen->StateNamesEnabled();
00334   // Warning on inconsistency with error-state names
00335   if(!StateNamesEnabled && (!rErrState1.empty()||!rErrState2.empty())) {
00336     FD_WARN("HioFreeInput: state names disabled in rResGen: error state names ignored.");
00337   }
00338   
00339   // prepare result, preserve StateNamesEnabled of rGen
00340   *pResGen=rGen;
00341   pResGen->StateNamesEnabled(StateNamesEnabled);
00342   pResGen->Name("HioFreeInput("+rGen.Name()+")");
00343   
00344   //create first error state, where inserted Input-events shall lead to:
00345   std::string errstate1;
00346   if(StateNamesEnabled) {
00347     errstate1=pResGen->UniqueStateName(rErrState1); 
00348     rErrState1Idx=pResGen->InsMarkedState(errstate1);
00349   }
00350   else {
00351     rErrState1Idx=pResGen->InsMarkedState();
00352   }
00353 
00354   //find Input-states
00355   StateSet::Iterator sit=pResGen->StatesBegin();
00356   EventSet::Iterator evit;
00357   bool InputInserted = false;
00358   for(;sit!=pResGen->StatesEnd();sit++){
00359     EventSet disabledInput;
00360     disabledInput = rInput - pResGen->ActiveEventSet(*sit);
00361     //if at least one Input-event is enabled AND at least one Input-event is disabled:
00362     //insert missing Input-transitions to error state
00363     if( (disabledInput!=rInput) && !disabledInput.Empty()) {
00364       FD_DF("HioFreeInput: " << *sit << " disabledInput: " << disabledInput.ToString()); 
00365       InputInserted = true;
00366       for (evit = disabledInput.Begin(); evit != disabledInput.End(); ++evit) {
00367         pResGen->SetTransition(*sit,*evit,rErrState1Idx);
00368       }       
00369     }
00370   }//for-loop through states
00371 
00372   //insert err_Input-state and connect both err-states with Input-Output-loop in case missing Input-events were inserted:
00373   if(InputInserted) {
00374     if(StateNamesEnabled) {
00375      FD_DF("HioFreeInput(...): inserted error state 1: " << errstate1 << " with Idx: " << rErrState1Idx);
00376     }
00377     else {
00378      FD_DF("HioFreeInput(...): inserted error state 1 with Idx: " << rErrState1Idx);
00379     }
00380     if(!rOutput.Empty()) { // this 'if' and the 'if' before are seperated because of the 'else' below !
00381        //create second error state
00382        std::string errstate2;
00383        if(StateNamesEnabled) {
00384          errstate2=pResGen->UniqueStateName(rErrState2);
00385          rErrState2Idx=pResGen->InsMarkedState(errstate2);
00386          FD_DF("HioFreeInput(...): inserted error state 2: " << errstate2);
00387       }
00388         else {
00389           rErrState2Idx=pResGen->InsMarkedState();
00390           FD_DF("HioFreeInput(...): inserted error state 2 with Idx: " << rErrState2Idx);
00391       }
00392          
00393          //insert Input-events:
00394          for (evit = rInput.Begin(); evit != rInput.End(); ++evit) {
00395             pResGen->SetTransition(rErrState2Idx,*evit,rErrState1Idx);
00396          }
00397          //insert output-events:
00398          for (evit = rOutput.Begin(); evit != rOutput.End(); ++evit) {
00399            pResGen->SetTransition(rErrState1Idx,*evit,rErrState2Idx);
00400          }
00401     }
00402   }
00403    //else delete err_Output-state
00404    else {
00405      pResGen->DelState(rErrState1Idx);
00406     }
00407    // if necessary, move pResGen to rResGen
00408   if(pResGen != &rResGen) {
00409     pResGen->Move(rResGen);
00410     delete pResGen;
00411   }
00412 }
00413 
00414 // HioFreeInput(rGen,rInput,rOutput,rResGen,rErrState1,rErrState2) 
00415 void HioFreeInput(
00416   const Generator& rGen, 
00417   const EventSet& rInput, 
00418   const EventSet& rOutput,
00419   Generator& rResGen,
00420   const std::string& rErrState1, 
00421   const std::string& rErrState2) {
00422   Idx errstate1,errstate2;
00423   HioFreeInput(rGen,rInput,rOutput,rResGen,rErrState1,rErrState2,errstate1,errstate2);
00424 }
00425 
00426 // HioFreeInput(rGen,rInput,rOutput,rResGen) 
00427 void HioFreeInput(
00428   const Generator& rGen, 
00429   const EventSet& rInput, 
00430   const EventSet& rOutput,
00431   Generator& rResGen)
00432 {
00433   //Call HioFreeInput with empty names for error states
00434   std::string ErrState1,ErrState2;
00435   HioFreeInput(rGen,rInput,rOutput,rResGen,ErrState1,ErrState2);
00436 }
00437 
00438 // HioFreeInput(HioPlant,HioPlant) 
00439 void HioFreeInput(
00440   const HioPlant& rPlant,
00441   HioPlant& rResPlant) 
00442 {
00443 
00444   FD_DF("HioFreeInput( [plant] " << rPlant.Name() << ")");
00445 
00446   // Call HioFreeInput with certain names for error state,
00447   // set Err-flag
00448   Idx errstateUp,errstateUe,errstate2;
00449   std::string ErrState1,ErrState2;
00450   
00451   EventSet NoOutput,uP,uE,yP,yE;  
00452   uP=rPlant.UpEvents();
00453   uE=rPlant.UeEvents();
00454   yP=rPlant.YpEvents();
00455   yE=rPlant.YeEvents();
00456   
00457   ErrState1="UpError";
00458   HioFreeInput(rPlant,uP,NoOutput,rResPlant,ErrState1,ErrState2,errstateUp,errstate2);
00459   
00460   ErrState1="UeError";
00461   HioFreeInput(rResPlant,uE,NoOutput,rResPlant,ErrState1,ErrState2,errstateUe,errstate2);
00462   
00463   // set HioStateFlag Err
00464   if(rResPlant.ExistsState(errstateUp)) rResPlant.SetErr(errstateUp);
00465   if(rResPlant.ExistsState(errstateUe)) rResPlant.SetErr(errstateUe);
00466   
00467   // restore event attributes
00468   rResPlant.SetYp(yP);
00469   rResPlant.SetUp(uP);
00470   rResPlant.SetYe(yE);
00471   rResPlant.SetUe(uE);
00472   
00473 }
00474 
00475 // HioFreeInput(HioController,HioController)   
00476 void HioFreeInput(
00477   const HioController& rController,
00478   HioController& rResController)  
00479 {
00480   FD_DF("HioFreeInput( [controller] " << rController.Name() << ")");
00481 
00482   HioController* pResController = &rResController;
00483   if(&rResController== &rController) {
00484     pResController=rResController.New();
00485   }  
00486   
00487   // check for enabled state names:
00488   bool StateNamesEnabled = pResController->StateNamesEnabled();
00489   
00490   // prepare error state names
00491   std::string errStr1, errStr2;
00492   
00493   // prepare error state indeces
00494   Idx errIdx1, errIdx2;
00495   
00496   // prepare result, preserve StateNamesEnabled of rGen
00497   pResController->Assign(rController);
00498   //*pResController=rController; // didn't work (should work ... check!!)
00499   //pResController=&rController; // didn't work (cannot work anyway)
00500   pResController->StateNamesEnabled(StateNamesEnabled);
00501   pResController->Name("HioFreeInput("+rController.Name()+")");
00502   
00503   // figure input alphabets
00504   EventSet UcEvents = rController.UcEvents();
00505   EventSet YpEvents = rController.YpEvents();
00506   EventSet YcEvents = rController.YcEvents();
00507   EventSet UpEvents = rController.UpEvents();
00508   
00509   //create first error state, where inserted Uc- or Yp-events shall lead to:
00510   if(StateNamesEnabled) {
00511   errStr1=pResController->UniqueStateName("UcYpError"); 
00512   errIdx1=pResController->InsMarkedState(errStr1);
00513   }
00514   else {
00515   errIdx1=pResController->InsMarkedState();
00516   }
00517   // set HioStateFlag Err
00518   pResController->SetErr(errIdx1);
00519   
00520   // set state attribute QUp
00521   pResController->SetQUp(errIdx1);
00522   
00523   //find Input-states
00524   StateSet::Iterator sit=pResController->StatesBegin();
00525   EventSet::Iterator evit;
00526   bool InputInserted = false;
00527   for(;sit!=pResController->StatesEnd();sit++){
00528     EventSet disabledInput, active;
00529   active = pResController->ActiveEventSet(*sit);
00530   // first treat Uc-events
00531     disabledInput = UcEvents - active;
00532     //if at least one Input-event is enabled AND at least one Input-event is disabled:
00533     //insert missing Input-transitions to error state
00534     if( (disabledInput!=UcEvents) && !disabledInput.Empty()) {
00535       // FD_DF("HioFreeInput: " << *sit << " disabledInput: " << disabledInput.ToString());
00536       InputInserted = true;
00537       for (evit = disabledInput.Begin(); evit != disabledInput.End(); ++evit) {
00538         pResController->SetTransition(*sit,*evit,errIdx1);
00539       }       
00540     }
00541   // then treat Yp-events
00542   disabledInput = YpEvents - active;
00543     //if at least one Input-event is enabled AND at least one Input-event is disabled:
00544     //insert missing Input-transitions to error state
00545     if( (disabledInput!=YpEvents) && !disabledInput.Empty()) {
00546       // FD_DF("HioFreeInput: " << *sit << " disabledInput: " << disabledInput.ToString());
00547       InputInserted = true;
00548       for (evit = disabledInput.Begin(); evit != disabledInput.End(); ++evit) {
00549         pResController->SetTransition(*sit,*evit,errIdx1);
00550       }       
00551     }
00552   }//for-loop through states
00553 
00554   //insert err_Input-state and connect both err-states with Input-Output-loop in case missing Input-events were inserted:
00555   if(InputInserted) {
00556      //create second error state
00557    std::string errstate2;
00558    if(StateNamesEnabled) {
00559      FD_DF("HioFreeInput(...): inserted error state 1: " << errStr1);
00560      errStr2=pResController->UniqueStateName("ErrorQYp"); 
00561      errIdx2=pResController->InsMarkedState(errStr2);
00562      FD_DF("HioFreeInput(...): inserted error state 2: " << errStr2);
00563     }
00564    else {
00565      FD_DF("HioFreeInput(...): inserted error state 1 with Idx: " << errIdx1);
00566      errIdx2=pResController->InsMarkedState();
00567      FD_DF("HioFreeInput(...): inserted error state 2 with Idx: " << errIdx2);
00568     }
00569    
00570    // set HioStateFlag Err
00571    pResController->SetErr(errIdx2);
00572    // set HioStateFlag QYp
00573    pResController->SetQYp(errIdx2);
00574    
00575      //insert Up-events:
00576      for (evit = UpEvents.Begin(); evit != UpEvents.End(); ++evit) {
00577      pResController->SetTransition(errIdx1,*evit,errIdx2);
00578     }
00579    //insert Yp-events:
00580      for (evit = YpEvents.Begin(); evit != YpEvents.End(); ++evit) {
00581      pResController->SetTransition(errIdx2,*evit,errIdx1);
00582     }
00583   }
00584   
00585    //else delete error-state 1
00586    else {
00587      pResController->DelState(errIdx1);
00588     }
00589 
00590    // if necessary, move pResGen to rResGen
00591   if(pResController != &rResController) {
00592     pResController->Move(rResController);
00593     delete pResController;
00594   } 
00595    // restore event attributes
00596    rResController.SetYc(YcEvents);
00597    rResController.SetUc(UcEvents);
00598    rResController.SetYp(YpEvents);
00599    rResController.SetUp(UpEvents);
00600 }
00601   
00602 // HioFreeInput(HioEnvironment,HioEnvironment)  
00603 void HioFreeInput(
00604   const HioEnvironment& rEnvironment,
00605   HioEnvironment& rResEnvironment) 
00606 {
00607   FD_DF("HioFreeInput( [environment] " << rEnvironment.Name() << ")");
00608 
00609   HioEnvironment* pResEnvironment = &rResEnvironment;
00610   if(&rResEnvironment== &rEnvironment) {
00611     pResEnvironment=rResEnvironment.New();
00612   }  
00613   
00614   // check for enabled state names:
00615   bool StateNamesEnabled = pResEnvironment->StateNamesEnabled();
00616   
00617   // prepare error state names
00618   std::string errStr1, errStr2;
00619   
00620   // prepare error state indeces
00621   Idx errIdx1, errIdx2;
00622   
00623   // prepare result, preserve StateNamesEnabled of rGen
00624   pResEnvironment->Assign(rEnvironment);
00625   //*pResEnvironment=rEnvironment; // didn't work
00626   //pResEnvironment=&rEnvironment; // didn't work
00627   pResEnvironment->StateNamesEnabled(StateNamesEnabled);
00628   pResEnvironment->Name("HioFreeInput("+rEnvironment.Name()+")");
00629   
00630   // figure alphabets
00631   EventSet UlEvents = rEnvironment.UlEvents();
00632   EventSet YeEvents = rEnvironment.YeEvents();
00633   EventSet YlEvents = rEnvironment.YlEvents();
00634   EventSet UeEvents = rEnvironment.UeEvents();
00635   
00636   //create first error state, where inserted Uc- or Yp-events shall lead to:
00637   if(StateNamesEnabled) {
00638   errStr1=pResEnvironment->UniqueStateName("UlYeError");  
00639   errIdx1=pResEnvironment->InsMarkedState(errStr1);
00640   }
00641   else {
00642   errIdx1=pResEnvironment->InsMarkedState();
00643   }
00644   
00645   // set HioStateFlag Err
00646   pResEnvironment->SetErr(errIdx1);
00647   // set HioStateFlag QUe
00648   pResEnvironment->SetQUe(errIdx1);
00649   
00650   //find Input-states
00651   StateSet::Iterator sit=pResEnvironment->StatesBegin();
00652   EventSet::Iterator evit;
00653   bool InputInserted = false;
00654   for(;sit!=pResEnvironment->StatesEnd();sit++){
00655     EventSet disabledInput, active;
00656   active = pResEnvironment->ActiveEventSet(*sit);
00657   // first treat Uc-events
00658     disabledInput = UlEvents - active;
00659     //if at least one Input-event is enabled AND at least one Input-event is disabled:
00660     //insert missing Input-transitions to error state
00661     if( (disabledInput!=UlEvents) && !disabledInput.Empty()) {
00662       // FD_DF("HioFreeInput: " << *sit << " disabledInput: " << disabledInput.ToString());
00663       InputInserted = true;
00664       for (evit = disabledInput.Begin(); evit != disabledInput.End(); ++evit) {
00665         pResEnvironment->SetTransition(*sit,*evit,errIdx1);
00666       }       
00667     }
00668   // then treat Yp-events
00669   disabledInput = YeEvents - active;
00670     //if at least one Input-event is enabled AND at least one Input-event is disabled:
00671     //insert missing Input-transitions to error state
00672     if( (disabledInput!=YeEvents) && !disabledInput.Empty()) {
00673       // FD_DF("HioFreeInput: " << *sit << " disabledInput: " << disabledInput.ToString());
00674       InputInserted = true;
00675       for (evit = disabledInput.Begin(); evit != disabledInput.End(); ++evit) {
00676         pResEnvironment->SetTransition(*sit,*evit,errIdx1);
00677       }       
00678     }
00679   }//for-loop through states
00680 
00681   //insert err_Input-state and connect both err-states with Input-Output-loop in case missing Input-events were inserted:
00682   if(InputInserted) {
00683      //create second error state
00684    std::string errstate2;
00685    if(StateNamesEnabled) {
00686      FD_DF("HioFreeInput(...): inserted error state 1: " << errStr1);
00687      errStr2=pResEnvironment->UniqueStateName("ErrorQYe");  
00688      errIdx2=pResEnvironment->InsMarkedState(errStr2);
00689      FD_DF("HioFreeInput(...): inserted error state 2: " << errStr2);
00690     }
00691    else {
00692      FD_DF("HioFreeInput(...): inserted error state 1 with Idx: " << errIdx1);
00693      errIdx2=pResEnvironment->InsMarkedState();
00694      FD_DF("HioFreeInput(...): inserted error state 2 with Idx: " << errIdx2);
00695     }
00696 
00697    // set HioStateFlag Err
00698    pResEnvironment->SetErr(errIdx2);
00699    // set state attribute QYe
00700    pResEnvironment->SetQYe(errIdx2);
00701    
00702      //insert Ue-events:
00703      for (evit = UeEvents.Begin(); evit != UeEvents.End(); ++evit) {
00704      pResEnvironment->SetTransition(errIdx1,*evit,errIdx2);
00705     }
00706    //insert Ye-events:
00707      for (evit = YeEvents.Begin(); evit != YeEvents.End(); ++evit) {
00708      pResEnvironment->SetTransition(errIdx2,*evit,errIdx1);
00709     }
00710   }
00711   
00712    //else delete error-state 1
00713    else {
00714      pResEnvironment->DelState(errIdx1);
00715     }
00716    // if necessary, move pResGen to rResGen
00717   if(pResEnvironment != &rResEnvironment) {
00718     pResEnvironment->Move(rResEnvironment);
00719     delete pResEnvironment;
00720   }
00721      // restore event attributes
00722    rResEnvironment.SetYl(YlEvents);
00723    rResEnvironment.SetUl(UlEvents);
00724    rResEnvironment.SetYe(YeEvents);
00725    rResEnvironment.SetUe(UeEvents);
00726 }
00727 
00728 // HioFreeInput(HioConstraint,HioConstraint)   
00729 void HioFreeInput(
00730   const HioConstraint& rConstraint,
00731   HioConstraint& rResConstraint) 
00732 {
00733   // Call HioFreeInput with certain names for error states,
00734   // set Err-flags
00735   Idx errstate1,errstate2;
00736   std::string ErrState1="Y-Error";
00737   std::string ErrState2="ErrorQY";
00738   EventSet y,u;
00739   y=rConstraint.YEvents();
00740   u=rConstraint.UEvents();
00741   HioFreeInput(rConstraint,y,u,rResConstraint,ErrState1,ErrState2,errstate1,errstate2);
00742   // set HioStateFlag Err
00743   rResConstraint.SetErr(errstate1);
00744   rResConstraint.SetErr(errstate2);
00745   // restore event attributes
00746   rResConstraint.SetY(y);
00747   rResConstraint.SetU(u);
00748 }
00749 
00750 // HioFreeInput(HioPlant) 
00751 void HioFreeInput(HioPlant& rPlant) {
00752   FD_DF("HioFreeInput( [single arg plant] " << rPlant.Name() << ")");
00753   HioFreeInput(rPlant,rPlant);
00754 }
00755 
00756 // HioFreeInput(HioController) 
00757 void HioFreeInput(HioController& rController) {
00758   HioFreeInput(rController,rController);
00759 }
00760 
00761 // HioFreeInput(HioEnvironment) 
00762 void HioFreeInput(HioEnvironment& rEnvironment) {
00763   HioFreeInput(rEnvironment,rEnvironment);
00764 }
00765 
00766 // HioFreeInput(HioConstraint) 
00767 void HioFreeInput(HioConstraint& rConstraint) {
00768   HioFreeInput(rConstraint,rConstraint);
00769 }
00770 
00771 
00772 
00773 //**********************************************************
00774 //******************** Completeness ************************
00775 //**********************************************************
00776 
00777 
00778 
00779 //**********************************************************
00780 //******************** I/O-shuffle ************************
00781 //**********************************************************
00782 
00783 //******************** current version: marked parameters + marking of alternation ************************
00784 
00785 // MarkHioShuffle(rGen1,rGen2,rMapOrigToResult,rShuffle)
00786 void MarkHioShuffle(const vGenerator& rGen1,const vGenerator& rGen2,
00787   const std::map< std::pair<Idx,Idx>, Idx >& rMapOrigToResult,
00788   vGenerator& rShuffle) {
00789   
00790   // invert mapOrigToResult (possible, as map is expected to be from parallel composition and thus must be bijective)
00791   std::map< Idx, std::pair<Idx,Idx> > mapResultToOrig;
00792   std::map< std::pair<Idx,Idx>, Idx >::const_iterator iter; 
00793     for( iter = rMapOrigToResult.begin(); iter != rMapOrigToResult.end(); ++iter ) {
00794       mapResultToOrig.insert(std::make_pair( iter->second, iter->first ));
00795     }
00796   
00797   // (I) duplicate all non-marked states, whose corresponding state in rGen1 or rGen2 is marked.
00798   StateSet nonmarked=rShuffle.States()-rShuffle.MarkedStates();
00799   StateSet::Iterator sit;
00800   std::map< Idx, Idx > rGen1Clones,rGen2Clones;
00801   for(sit = nonmarked.Begin(); sit != nonmarked.End(); sit ++) {
00802     // marked in rGen1?
00803     if(rGen1.ExistsMarkedState(mapResultToOrig[*sit].first)) {
00804       rGen1Clones[*sit]=rShuffle.InsMarkedState();
00805     }
00806     // marked in rGen2?
00807     if(rGen2.ExistsMarkedState(mapResultToOrig[*sit].first)) {
00808       rGen2Clones[*sit]=rShuffle.InsMarkedState();
00809     }
00810   }
00811   
00812   // (II) MOVE HEAD OF rGen1-transitions whose X2 has a rGen1-clone, and head of rGen2-transitions whose
00813   //        X2 has a rGen2-clone
00814   TransSet TransToClear, TransToSet;
00815     TransSet::Iterator tit=rShuffle.TransRelBegin();
00816   TransSet::Iterator tit_end=rShuffle.TransRelEnd();
00817   std::map<Idx,Idx>::iterator cloneit;
00818   bool x1hasGen1Clone,x1hasGen2Clone, x2hasClone;
00819   for(;tit!=tit_end;tit++) {
00820     
00821     x1hasGen1Clone=false;
00822     x1hasGen2Clone=false;
00823     x2hasClone=false;
00824   
00825     //##################################################
00826     // CASE (I) - X2 has clone: move head of transition, also duplicate transition if X1 has clone
00827     //##################################################
00828     
00829     // preliminarily check if X1 has clone
00830     cloneit=rGen1Clones.find(tit->X1);
00831     if(cloneit!=rGen1Clones.end()) x1hasGen1Clone=true;
00832     cloneit=rGen2Clones.find(tit->X1);
00833     if(cloneit!=rGen2Clones.end()) x1hasGen2Clone=true;
00834     
00835     
00836     // distinguish rGen1-events and rGen2-events
00837     if(rGen1.Alphabet().Exists(tit->Ev)) {
00838       // exists rGen1-clone?
00839       cloneit=rGen1Clones.find(tit->X2);
00840       if(cloneit!=rGen1Clones.end()) {
00841         x2hasClone=true;
00842         // move head to clone: delete original trans, insert moved trans
00843         TransToClear.Insert(*tit);
00844         TransToSet.Insert(tit->X1,tit->Ev,rGen1Clones[tit->X2]);
00845         // if X1 has a clone make copy starting from clone of X1
00846         if(x1hasGen1Clone) {
00847             TransToSet.Insert(rGen1Clones[tit->X1],tit->Ev,rGen1Clones[tit->X2]);
00848           }
00849         if(x1hasGen2Clone) {
00850             TransToSet.Insert(rGen2Clones[tit->X1],tit->Ev,rGen1Clones[tit->X2]);
00851           }
00852       }
00853     }
00854     
00855     //  else, tit is rGen2-transition
00856     else {
00857       // exists rGen2-clone?
00858       cloneit=rGen2Clones.find(tit->X2);
00859       if(cloneit!=rGen2Clones.end()) {
00860         x2hasClone=true;
00861         // move head to clone: delete original trans, insert moved trans
00862         TransToClear.Insert(*tit);
00863         TransToSet.Insert(tit->X1,tit->Ev,cloneit->second);
00864         // if X1 has a clone make copy starting from clone of X1
00865         if(x1hasGen1Clone) {
00866             TransToSet.Insert(rGen1Clones[tit->X1],tit->Ev,rGen2Clones[tit->X2]);
00867           }
00868         if(x1hasGen2Clone) {
00869             TransToSet.Insert(rGen2Clones[tit->X1],tit->Ev,rGen2Clones[tit->X2]);
00870           }
00871       }
00872     }
00873     
00874     //###################################################
00875     // CASE (II) - (only) X1 has clone: duplicate transition (see Case I for case also X2 has clone)
00876     //###################################################
00877     
00878     if( (x1hasGen1Clone||x1hasGen2Clone) && !x2hasClone ) {
00879       if(x1hasGen1Clone) TransToSet.Insert(rGen1Clones[tit->X1],tit->Ev,tit->X2);
00880       if(x1hasGen2Clone) TransToSet.Insert(rGen2Clones[tit->X1],tit->Ev,tit->X2);
00881     }
00882   }
00883   
00884   // clear invalid transitions
00885   tit=TransToClear.Begin();
00886   tit_end=TransToClear.End();
00887   for(;tit!=tit_end;tit++) rShuffle.ClrTransition(*tit);
00888   
00889   // set updated transitions
00890   tit=TransToSet.Begin();
00891   tit_end=TransToSet.End();
00892   for(;tit!=tit_end;tit++) rShuffle.SetTransition(*tit);
00893   
00894   // cosmetics
00895   rShuffle.Accessible();
00896   return;
00897 }
00898 
00899 // MarkAlternationAB(Aset,Bset,AltAB)
00900 void MarkAlternationAB(
00901   const EventSet rAset, 
00902   const EventSet rBset,
00903   Generator& rAltAB)
00904 {
00905   FD_DF("MarkAlternationAB()");
00906   
00907   #ifdef FAUDES_CHECKED
00908   // validate parameters
00909   if (rAset.Empty()){
00910     std::stringstream errstr;
00911     errstr << "Empty parameter rAset.";
00912     throw Exception("CheapAltAnB", errstr.str(), 0);
00913   } 
00914   if (rBset.Empty()){
00915       std::stringstream errstr;
00916       errstr << "Empty parameter rBset.";
00917       throw Exception("CheapAltAnB", errstr.str(), 0);
00918   }
00919   #endif
00920   
00921     rAltAB.Clear();
00922     rAltAB.InjectAlphabet(rAset+rBset);
00923     
00924     Idx s1,s2,s3,s4,s5;
00925     
00926     s1=rAltAB.InsInitState();
00927     rAltAB.SetMarkedState(s1);
00928     s2=rAltAB.InsMarkedState();
00929     s3=rAltAB.InsMarkedState();
00930     s4=rAltAB.InsState();
00931     s5=rAltAB.InsState();
00932     EventSet::Iterator evit=rAset.Begin();
00933     EventSet::Iterator evit_end=rAset.End();
00934     for(;evit!=evit_end;++evit) {
00935         rAltAB.SetTransition(s1,*evit,s2);
00936         rAltAB.SetTransition(s2,*evit,s4);
00937         rAltAB.SetTransition(s3,*evit,s2);
00938         rAltAB.SetTransition(s4,*evit,s4);
00939         rAltAB.SetTransition(s5,*evit,s2);
00940     }
00941     evit=rBset.Begin();
00942     evit_end=rBset.End();
00943     for(;evit!=evit_end;++evit) {
00944         rAltAB.SetTransition(s1,*evit,s3);
00945         rAltAB.SetTransition(s2,*evit,s3);
00946         rAltAB.SetTransition(s3,*evit,s5);
00947         rAltAB.SetTransition(s4,*evit,s3);
00948         rAltAB.SetTransition(s5,*evit,s5);
00949     }
00950 }
00951 
00952 // HioShuffleUnchecked(rPlantA,rPlantB,rYp,rUp,rYe,rUe,rIOShuffAB) 
00953 void HioShuffleUnchecked(
00954   const Generator& rPlantA, 
00955   const Generator& rPlantB, 
00956   const EventSet& rYp,
00957   const EventSet& rUp, 
00958   const EventSet& rYe, 
00959   const EventSet& rUe,
00960   Generator& rIOShuffAB) 
00961 { 
00962   FD_DF("HioShuffle()");
00963 
00964   //Extract alphabets:             
00965   EventSet A,B,SigmaP;
00966   A = rPlantA.Alphabet();
00967   B = rPlantB.Alphabet();
00968 
00969   // parallel composition of plantA and plantB (i.e. shuffle as there are no shared events)
00970   Generator parallel1, parallel2;
00971   std::map< std::pair<Idx,Idx>, Idx > MapOrigToResult;
00972   Parallel(rPlantA,rPlantB,MapOrigToResult,parallel1);
00973   MarkHioShuffle(rPlantA,rPlantB,MapOrigToResult,parallel1);
00974 
00975   // restrict to event pairs [(SigA SigA)*+(SigB SigB)*]*, which results
00976   // in correct I/O sorting L_IO.
00977   Generator EventPairs; // generator of above sorting language
00978   EventPairs.InjectAlphabet(A + B);
00979   Idx state1,state2,state3;
00980   state1=EventPairs.InsInitState("1");
00981   EventPairs.SetMarkedState(state1);
00982   state2=EventPairs.InsMarkedState("2");
00983   state3=EventPairs.InsMarkedState("3");
00984   EventSet::Iterator evit;
00985   for (evit = A.Begin(); evit != A.End(); ++evit) {
00986     EventPairs.SetTransition(state1,*evit,state2);
00987     EventPairs.SetTransition(state2,*evit,state1);
00988   }
00989   for (evit = B.Begin(); evit != B.End(); ++evit) {
00990     EventPairs.SetTransition(state1,*evit,state3);
00991     EventPairs.SetTransition(state3,*evit,state1);
00992   }
00993   Parallel(parallel1,EventPairs,parallel2);
00994   parallel1 = parallel2;
00995 
00996 // //#####################################################################################
00997 // //#####################################################################################
00998 // //#####################################################################################
00999 //  //restrict to IO-sorting structure with forced alternation:
01000 //
01001 //  // Old Vers before Dez 4 2006: Alternation of whole alphabets
01002 //  A = rPlantA.Alphabet();
01003 //  B = rPlantB.Alphabet();
01004 //
01005 //
01006 ////  // New Vers: Alternation of YP Events only
01007 ////  // -> currently leads to normality problems during superposed controller synthesis
01008 ////  SigmaP.SetUnion(rYp);
01009 ////  SigmaP.SetUnion(rUp);
01010 ////  A.SetIntersection(SigmaP);
01011 ////  B.SetIntersection(SigmaP);
01012 //
01013 //
01014 //
01015 //  Generator AltAB;
01016 //  A.Name("A");
01017 //  B.Name("B");
01018 //  CheapAltAB(A,B,Depth,AltAB);
01019 //  // Alt_AB.Write("tmp_Alternation_AB.gen");
01020 //  Parallel(parallel2, AltAB, parallel1);
01021 //  //parallel2.Write("tmp_IOS3.gen");
01022 //
01023 //
01024 //
01025 
01026   
01027   // bugfix to resolve normality problem: whenever plant A
01028   // can send a yp-event and at the same time plant B can
01029   // send a ye-event, then let the ye-event be sent first:
01030   //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01031   //*** Environment-first policy: If, in some state both, Yp- and Ye events are
01032   //*** active, then cancel all Yp-transitions in this state, as environment has
01033   //*** to be updated first.
01034   
01035   FD_DF("------ HioShuffle with Environment-First-Policy! -----");
01036   
01037   // loop all states
01038   StateSet::Iterator sit = parallel1.StatesBegin();
01039   StateSet::Iterator sit_end = parallel1.StatesEnd();
01040   
01041   for(; sit != sit_end; sit++)
01042   {
01043         // figure active Yp-events and active Ye-events
01044         //std::cout << "End: " << *sit_end <<"...done: " << *sit << std::endl;
01045         EventSet ActiveYe;
01046         EventSet ActiveYp = parallel1.TransRel().ActiveEvents(*sit);
01047         ActiveYe=ActiveYp;
01048         ActiveYe.SetIntersection(rYe);
01049         ActiveYp.SetIntersection(rYp);
01050         if (!(ActiveYe.Empty())&& !(ActiveYp.Empty()))
01051         {   
01052             TransSet TransToClear;
01053             TransSet::Iterator tit=parallel1.TransRelBegin(*sit);
01054             TransSet::Iterator tit_end=parallel1.TransRelEnd(*sit);
01055             for(;tit!=tit_end;tit++)
01056                 {
01057                 //std::cout << "finding Yp-events to delete... "; 
01058                 if(ActiveYp.Exists(tit->Ev))
01059                     {
01060                     TransToClear.Insert(*tit);
01061                     }
01062                 }
01063             tit=TransToClear.Begin();
01064             tit_end=TransToClear.End();
01065             for(;tit!=tit_end;tit++)
01066             {
01067             //std::cout<<" ...deleting" <<std::endl;
01068             parallel1.ClrTransition(*tit);
01069             }
01070         } 
01071   }  
01072   
01073   //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01074 
01075 
01076 
01077 //~ ////
01078 //~ // //#####################################################################################
01079 //~ // //#####################################################################################
01080 //~ // //#####################################################################################
01081 
01082 
01083   // Insert Error Behaviour, i.e. make UP and UE free in (YP,UP)-port of result:
01084   // free UP:
01085   HioFreeInput(parallel1, rUp, rYp, parallel2, "errYp_Ye", "errUp");
01086   //parallel1.Write("tmp_IOS4.gen");
01087   // free UE:
01088   HioFreeInput(parallel2, rUe, rYe, parallel1, "errYp_Ye", "errUe");
01089   //parallel2.Write("tmp_IOS5.gen");
01090   
01091   // Mark Alternation of YP-events
01092   A.SetIntersection(rYp);
01093   B.SetIntersection(rYp);
01094   MarkAlternationAB(A,B,parallel2);
01095   Parallel(parallel2,parallel1,parallel1);
01096 
01097   rIOShuffAB = parallel1;
01098   rIOShuffAB.Name("HioShuffle("+rPlantA.Name()+rPlantB.Name()+")");
01099   return;
01100 }
01101 
01102 
01103 // HioShuffle(rPlantA,rPlantB,rYp,rUp,rYe,rUe,rIOShuffAB) 
01104 void HioShuffle(
01105   const Generator& rPlantA, 
01106   const Generator& rPlantB, 
01107   const EventSet& rYp,
01108   const EventSet& rUp, 
01109   const EventSet& rYe, 
01110   const EventSet& rUe,
01111   Generator& rIOShuffAB) 
01112 { 
01113   rIOShuffAB.Clear();
01114   #ifdef FAUDES_CHECKED
01115   // exception on empty alphabets
01116   if (rYp.Empty()){
01117    std::stringstream errstr;
01118    errstr << "Empty Yp alphabet\n";
01119    throw Exception("HioShuffle", errstr.str(), 0);
01120   }
01121   if (rUp.Empty()){
01122    std::stringstream errstr;
01123    errstr << "Empty Up alphabet\n";
01124    throw Exception("HioShuffle", errstr.str(), 0);
01125   }
01126   if (rYe.Empty()){
01127    std::stringstream errstr;
01128    errstr << "Empty Ye alphabet\n";
01129    throw Exception("HioShuffle", errstr.str(), 0);
01130   }
01131   if (rUe.Empty()){
01132    std::stringstream errstr;
01133    errstr << "Empty Ue alphabet\n";
01134    throw Exception("HioShuffle", errstr.str(), 0);
01135   }
01136   
01137   // create resulting alphabet while checking for disjoint sets
01138   EventSet alphabet,alphabetA,alphabetB,errevents;
01139   alphabetA=rPlantA.Alphabet();
01140   alphabetB=rPlantB.Alphabet();
01141   // initialize with rYp
01142   alphabet.SetUnion(rYp);
01143   // insert remaining events one by one and check if new
01144   EventSet::Iterator evit;
01145   // rUp
01146   for (evit = rUp.Begin(); evit != rUp.End(); ++evit) {
01147     if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
01148   }
01149   // rYe
01150   for (evit = rYe.Begin(); evit != rYe.End(); ++evit) {
01151     if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
01152   }
01153   // rUe
01154   for (evit = rUe.Begin(); evit != rUe.End(); ++evit) {
01155     if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
01156   }
01157   // throw exception on non disjoint alphabets
01158   if (!errevents.Empty()){
01159     std::stringstream errstr;
01160     errstr << "Non-disjoint parameters; ambiguous events:\n" <<errevents.ToString();
01161   throw Exception("HioShuffle", errstr.str(), 0);
01162   }
01163   
01164   // check alphabet match with plant A and B-alphabets:
01165   // The union of plant A and B alphabets need not equal but must be included in the union of EventSet parameters.
01166   
01167   errevents=alphabetA+alphabetB-alphabet;
01168   if (!errevents.Empty()){
01169     std::stringstream errstr;
01170     errstr << "Plant A- or plant B-events missing in Yp,Up,Ye or Ue:\n" <<errevents.ToString();
01171   throw Exception("HioShuffle", errstr.str(), 0);
01172   }
01173   
01174   // plant A and plant B must be in HioPlantForm
01175   HioPlant hioPlantA=HioPlant(rPlantA,rYp*alphabetA,rUp*alphabetA,rYe*alphabetA,rUe*alphabetA);
01176   std::string report;
01177   if(!IsHioPlantForm(hioPlantA,report)){
01178     std::stringstream errstr;
01179     errstr << "plant A not in HioPlantForm:\n" << report;
01180   throw Exception("HioShuffle", errstr.str(), 0);
01181   }
01182   
01183   HioPlant hioPlantB=HioPlant(rPlantB,rYp*alphabetB,rUp*alphabetB,rYe*alphabetB,rUe*alphabetB);
01184   report.clear();
01185   if(!IsHioPlantForm(hioPlantB,report)){
01186     std::stringstream errstr;
01187     errstr << "plant B not in HioPlantForm:\n" << report;
01188   throw Exception("HioShuffle", errstr.str(), 0);
01189   }
01190   #endif
01191   
01192   // compute I/O-shuffle 
01193   HioShuffleUnchecked(rPlantA, rPlantB, rYp, rUp, rYe, rUe, rIOShuffAB);
01194   
01195 }
01196 
01197 void HioShuffle(
01198   const HioPlant& rPlantA, 
01199   const HioPlant& rPlantB,
01200   HioPlant& rIOShuffAB) {
01201   
01202   //prepare result
01203   rIOShuffAB.Clear();
01204   
01205   EventSet yp = rPlantA.YpEvents()+rPlantB.YpEvents();
01206   EventSet up = rPlantA.UpEvents()+rPlantB.UpEvents();
01207   EventSet ye = rPlantA.YeEvents()+rPlantB.YeEvents();
01208   EventSet ue = rPlantA.UeEvents()+rPlantB.UeEvents();
01209   
01210   // compute I/O-shuffle
01211   HioShuffle(rPlantA, rPlantB, yp, up, ye, ue, rIOShuffAB);
01212   
01213   // set event and state attributes
01214   rIOShuffAB.SetYp(yp);
01215   rIOShuffAB.SetUp(up);
01216   rIOShuffAB.SetYe(ye);
01217   rIOShuffAB.SetUe(ue);
01218   
01219   IsHioPlantForm(rIOShuffAB);
01220 }
01221 //******************** old version: no marking, forced alternation ************************
01222 
01223 // CheapAltAnB(rAset,rBset,Depth,rAltAnB)
01224 void CheapAltAnB(
01225   const EventSet rAset, 
01226   const EventSet rBset,
01227   const int Depth,
01228   Generator& rAltAnB) 
01229 { 
01230   FD_DF("CheapAltAnB()");
01231   
01232   // validate parameters
01233   if (Depth<1){
01234       std::stringstream errstr;
01235       errstr << "Parameter Depth must be 1 or greater.";
01236       throw Exception("CheapAltAnB", errstr.str(), 0);
01237   }
01238   #ifdef FAUDES_CHECKED
01239   if (rAset.Empty()){
01240       std::stringstream errstr;
01241       errstr << "Empty parameter rAset.";
01242       throw Exception("CheapAltAnB", errstr.str(), 0);
01243   } 
01244   if (rBset.Empty()){
01245       std::stringstream errstr;
01246       errstr << "Empty parameter rBset.";
01247       throw Exception("CheapAltAnB", errstr.str(), 0);
01248   }
01249   #endif
01250   
01251   // prepare result
01252   rAltAnB.Clear();
01253   rAltAnB.Name("CheapAltAnB(" + rAset.Name() + "," + rBset.Name() + "," + ToStringInteger(Depth) + ")");
01254 
01255   // create initial state
01256   Idx init = rAltAnB.InsInitState("alt_"+rAset.Name()+"_init");
01257   rAltAnB.SetMarkedState(init);
01258   
01259   Idx last = init;
01260   rAltAnB.InjectAlphabet(rAset + rBset);
01261 
01262   // selfloop initial state with Bset:
01263   EventSet::Iterator evit;
01264   for (evit = rBset.Begin(); evit != rBset.End(); ++evit) {
01265       rAltAnB.SetTransition(last,*evit,last);
01266   }
01267 
01268   //create n concatenated pathes A->|a|A->|b| and transitions B from |b| to initial state.
01269   for (int i=0; i!=Depth; ++i) {
01270     Idx a = rAltAnB.InsMarkedState("alt_"+rAset.Name()+"_U"+ToStringInteger(i+1));
01271     Idx b = rAltAnB.InsMarkedState("alt_"+rAset.Name()+"_Y"+ToStringInteger(i+2));
01272     //connect last,a and b with A-transitions.
01273     for (evit = rAset.Begin(); evit != rAset.End(); ++evit) {
01274       rAltAnB.SetTransition(last,*evit,a);
01275       rAltAnB.SetTransition(a,*evit,b);
01276     }
01277     //insert B-transitions from b to init
01278     for (evit = rBset.Begin(); evit != rBset.End(); ++evit) {
01279       rAltAnB.SetTransition(b,*evit,init);
01280     }
01281     last = b;
01282   }
01283 }
01284 
01285 // CheapAltAB(rAset,rBset,Depth,rAltAnB)
01286 void CheapAltAB(
01287   const EventSet rAset, 
01288   const EventSet rBset,  
01289   const int Depth,
01290   Generator& rAltAB) 
01291 { 
01292   FD_DF("CheapAltAB()");
01293   // prepare result
01294   rAltAB.Clear();
01295   
01296   Generator AnB, BnA;
01297   CheapAltAnB(rAset,rBset,Depth,AnB);
01298   CheapAltAnB(rBset,rAset,Depth,BnA);
01299   Parallel(AnB,BnA,rAltAB);
01300   rAltAB.Name("CheapAltAB("+rAset.Name()+","+rBset.Name()+","+ToStringInteger(Depth)+")");
01301 }
01302 
01303 // HioShuffleTU(rPlantA,rPlantB,rYp,rUp,rYe,rUe,Depth,rIOShuffAB) 
01304 void HioShuffleTU(
01305   const Generator& rPlantA, 
01306   const Generator& rPlantB, 
01307   const EventSet& rUp, 
01308   const EventSet& rYp,
01309   const EventSet& rYe, 
01310   const EventSet& rUe,
01311   const int Depth,
01312   Generator& rIOShuffAB) 
01313 { 
01314   FD_DF("HioShuffle()");
01315 
01316   //Extract alphabets:             
01317   EventSet A,B,SigmaP;
01318   A = rPlantA.Alphabet();
01319   B = rPlantB.Alphabet();
01320 
01321   // parallel composition of plantA and plantB (i.e. shuffle as there are no shared events)
01322   Generator parallel1, parallel2;
01323   Parallel(rPlantA,rPlantB,parallel1);
01324 
01325   // restrict to event pairs [(SigA SigA)*+(SigB SigB)*]*, which results
01326   // in correct I/O sorting L_IO.
01327   Generator EventPairs; // generator of above sorting language
01328   EventPairs.InjectAlphabet(A + B);
01329   Idx state1,state2,state3;
01330   state1=EventPairs.InsInitState("1");
01331   EventPairs.SetMarkedState(state1);
01332   state2=EventPairs.InsMarkedState("2");
01333   state3=EventPairs.InsMarkedState("3");
01334   EventSet::Iterator evit;
01335   for (evit = A.Begin(); evit != A.End(); ++evit) {
01336     EventPairs.SetTransition(state1,*evit,state2);
01337     EventPairs.SetTransition(state2,*evit,state1);
01338   }
01339   for (evit = B.Begin(); evit != B.End(); ++evit) {
01340     EventPairs.SetTransition(state1,*evit,state3);
01341     EventPairs.SetTransition(state3,*evit,state1);
01342   }
01343   Parallel(parallel1,EventPairs,parallel2);
01344 
01345   //restrict to IO-sorting structure with forced alternation:
01346 
01347 ////////  // Old Vers before Dez 4 2006: Alternation of whole alphabets
01348 ////////  A = rPlantA.Alphabet();
01349 ////////  B = rPlantB.Alphabet();
01350 //////
01351 //////  // New Vers: Alternation of YP Events only
01352 //////  // -> currently leads to normality problems during superposed controller synthesis
01353 //////  SigmaP.SetUnion(rYp);
01354 //////  SigmaP.SetUnion(rUp);
01355 //////  A.SetIntersection(SigmaP);
01356 //////  B.SetIntersection(SigmaP);
01357 //////
01358 //////
01359 //////  Generator AltAB;
01360 //////  A.Name("A");
01361 //////  B.Name("B");
01362 //////  CheapAltAB(A,B,Depth,AltAB);
01363 //////  // Alt_AB.Write("tmp_Alternation_AB.gen");
01364 //////  Parallel(parallel2, AltAB, parallel1);
01365 //////  //parallel2.Write("tmp_IOS3.gen");
01366 
01367   // Old Vers before Dez 4 2006: Alternation of whole alphabets
01368   EventSet Ap, Bp, Ae, Be, SigmaE;
01369   
01370   Ap = rPlantA.Alphabet();
01371   Bp = rPlantB.Alphabet();
01372   
01373   Ae = rPlantA.Alphabet();
01374   Be = rPlantB.Alphabet();
01375   
01376   
01377 
01378   //*************************************************************************
01379   //// New Vers: Alternation of YP Events only
01380   //// -> currently leads to normality problems during superposed controller synthesis
01381   SigmaP.SetUnion(rYp);
01382   SigmaP.SetUnion(rUp);
01383   Ap.SetIntersection(SigmaP);
01384   Bp.SetIntersection(SigmaP);
01385   
01386   SigmaE.SetUnion(rYe);
01387   SigmaE.SetUnion(rUe);
01388   Ae.SetIntersection(SigmaE);
01389   Be.SetIntersection(SigmaE);
01390   
01391   
01392   //*************************************************************************
01393   Generator AltAB;
01394   Ap.Name("A");
01395   Bp.Name("B");
01396   CheapAltAB(Ap,Bp,Depth,AltAB);
01397   // Alt_AB.Write("tmp_Alternation_AB.gen");
01398   Parallel(parallel2, AltAB, parallel1);
01399   
01400 /*   // bugfix to resolve normality problem: whenever plant A
01401  *  // can send a yp-event and at the same time plant B can
01402  *  // send a ye-event, then let the ye-event be sent first:
01403  *   //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01404  *   // Environment-first policy: If, in some state both, Yp- and Ye events are
01405  *   // active, then cancel all Yp-transitions in this state, as environment has
01406  *   // to be updated first.
01407  *   
01408  *   // loop all states
01409  *   StateSet::Iterator sit = parallel1.StatesBegin();
01410  *   StateSet::Iterator sit_end = parallel1.StatesEnd();
01411  *   
01412  *   for(; sit != sit_end; sit++)
01413  *   {
01414  *         // figure active Yp-events and active Ye-events
01415  *         //std::cout << "End: " << *sit_end <<"...done: " << *sit << std::endl;
01416  *         EventSet ActiveYe;
01417  *         EventSet ActiveYp = parallel1.TransRel().ActiveEvents(*sit);
01418  *         ActiveYe=ActiveYp;
01419  *         ActiveYe.SetIntersection(rYe);
01420  *         ActiveYp.SetIntersection(rYp);
01421  *         if (!(ActiveYe.Empty())&& !(ActiveYp.Empty()))
01422  *         {   
01423  *             TransSet TransToClear;
01424  *             TransSet::Iterator tit=parallel1.TransRelBegin(*sit);
01425  *             TransSet::Iterator tit_end=parallel1.TransRelEnd(*sit);
01426  *             for(;tit!=tit_end;tit++)
01427  *                 {
01428  *                 //std::cout << "finding Yp-events to delete... "; 
01429  *                 if(ActiveYp.Exists(tit->Ev))
01430  *                     {
01431  *                     TransToClear.Insert(*tit);
01432  *                     }
01433  *                 }
01434  *             tit=TransToClear.Begin();
01435  *             tit_end=TransToClear.End();
01436  *             for(;tit!=tit_end;tit++)
01437  *             {
01438  *             //std::cout<<" ...deleting" <<std::endl;
01439  *             parallel1.ClrTransition(*tit);
01440  *             }
01441  *         } 
01442  *   }  
01443  *   
01444  *   //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01445  * 
01446  */
01447 
01448 
01449   // Insert Error Behaviour, i.e. make UP and UE free in (YP,UP)-port of result:
01450   // free UP:
01451   HioFreeInput(parallel1, rUp, rYp, parallel2, "errYp_Ye", "errUp");
01452   //parallel1.Write("tmp_IOS4.gen");
01453   // free UE:
01454   HioFreeInput(parallel2, rUe, rYe, parallel1, "errYp_Ye", "errUe");
01455   //parallel2.Write("tmp_IOS5.gen");
01456 
01457   rIOShuffAB = parallel1;
01458 }
01459 
01460 //**********************************************************
01461 //******************** Cycles ************************
01462 //**********************************************************
01463 
01464 
01465 // ***Search for strongly connected ycless components (SCC)***
01466 // This function partitions the stateset of a generator into equivalent classes
01467 // such that states x1 and x2 are equivalent iff there is a ycless path from x1
01468 // to x2 AND a ycless path from x2 to x1.
01469 // This function implements the algorithm based on a depth first search
01470 // presented in:
01471 // -Aho, Hopcroft, Ullman: The Design and Analysis of Computer Algorithms-
01472 //
01473 // Most of the comments in this function have been literally taken from
01474 // this book!
01475 //
01476 // Parameters (an api with generator and Yc-events as input and SCCs as output
01477 // is provided right below this method.)
01478 // -state: State, from which the current recursion is started.
01479 // -rcount: denotes the current depth of the recursion.
01480 // -Yc: set of Yc-events
01481 // -UnMarkedOnly: if set true, being unmarked is an additional condition for equivalence of states
01482 // -NewStates: Set of states that up to now were not found by the depth first search
01483 // -STACK: stack of state indeces
01484 // -StackStates: set of states whose indeces are on STACK.
01485 // -DFN: map assigning to each state its Depth-First Number
01486 // -LOWLINK: map assigning to each state its LOWLINK Number
01487 // -SCCset: result - the set of strongly connected components
01488 // -UnMarkedSCCset: result - the set of strongly connected components consisting exclusively of marked states
01489 // -Roots: result - the set of states that each are root of some SCC.
01490 //
01491 // ToDo: handle exceptions.
01492 //
01493 
01494 void SearchYclessScc(
01495   const Idx state, 
01496   int& rcount,      // why is this a ref?
01497   const Generator& rGen,
01498   const EventSet& rYc,
01499   const bool UnMarkedOnly,
01500   StateSet&  rNewStates,
01501   std::stack<Idx>& rSTACK, 
01502   StateSet& rStackStates,
01503   std::map<const Idx, int>& rDFN,
01504   std::map<const Idx, int>& rLOWLINK,
01505   std::set<StateSet>& rSccSet,
01506   StateSet& rRoots)
01507 {
01508   FD_DF("SerchYclessScc: -- search from state "<< state << "--");
01509 
01510   // mark state "old";
01511   rNewStates.Erase(state);
01512 
01513   // DFNUMBER[state] <- count;
01514   rDFN[state]=rcount;
01515 
01516   // count <- count+1;
01517   rcount++;
01518 
01519   // LOWLINK[v] <- DFNUMBER[v];
01520   rLOWLINK[state]=rDFN[state];
01521   //cout<<"count: "<<rcount<<" state: "<<state<<" DFN: "<<rDFN[state]<<endl;
01522 
01523   // push state on STACK;
01524   rSTACK.push(state);
01525   rStackStates.Insert(state);
01526 
01527   //<<create set "L[state]" of successor states of state, without states reached via a Yc-event:
01528   StateSet SuccStates = StateSet();
01529   TransSet::Iterator it = rGen.TransRelBegin(state);
01530   TransSet::Iterator it_end = rGen.TransRelEnd(state);
01531   for (; it != it_end; ++it) {
01532     if(!rYc.Exists(it->Ev)||(UnMarkedOnly &! rGen.ExistsMarkedState(it->X2)))
01533       {
01534         SuccStates.Insert(it->X2);
01535       }
01536   }
01537 
01538   // for each vertex *sit on L[state] do
01539   StateSet::Iterator sit = SuccStates.Begin();
01540   StateSet::Iterator sit_end = SuccStates.End();
01541   for (; sit != sit_end; ++sit)
01542     {
01543       // if *sit is marked "new" then
01544       if(rNewStates.Exists(*sit))
01545         {// begin
01546         
01547     // SearchC(*sit);
01548     SearchYclessScc(*sit, rcount, rGen, rYc, UnMarkedOnly, rNewStates, rSTACK, rStackStates, rDFN, rLOWLINK, rSccSet, rRoots);
01549     // LOWLINK[state] <- MIN(LOWLINK[state],LOWLINK[*sit]);
01550     if(rLOWLINK[*sit]<rLOWLINK[state])
01551       {
01552         rLOWLINK[state]=rLOWLINK[*sit];
01553       }
01554         }//end
01555         
01556       else
01557         {
01558     // if DFNUMBER[*sit]<DFNUMBER[state] and [*sit] is on STACK then
01559     if((rDFN[*sit]<rDFN[state])&&(rStackStates.Exists(*sit)))
01560       {
01561         // LOWLINK[state]<-MIN(DFNUMBER[*sit],LOWLINK[state]);
01562         if(rDFN[*sit]<rLOWLINK[state])
01563     {
01564       rLOWLINK[state]=rDFN[*sit];
01565     }
01566       }                
01567         }
01568     }//end for
01569   // if LOWLINK[state]=DFNUMBER[state] (i.e. state is root of a SCC) then
01570   if((rLOWLINK[state]==rDFN[state]))
01571     {
01572       // per def., each state in a graph is element of a SCC, thus:
01573       // check if size of SCC is>1 or (else) SCC contains (non-{epsilon,yc}-)selfloops
01574       // to avoid print of trivial SCCs
01575       bool realscc=rSTACK.top()!=state; //size of SCC>1 ? if not, check for selfloops:
01576       if(!realscc)
01577         {
01578     TransSet::Iterator it = rGen.TransRelBegin(state);
01579     TransSet::Iterator it_end = rGen.TransRelEnd(state);
01580     for (; it != it_end; ++it)
01581             {
01582         if((it->X2==state)&&(!rYc.Exists(it->Ev)))
01583                 {
01584       realscc=true; //at least one yc-less selfloop found -> SCC is nontrivial
01585       break;
01586                 }
01587             }
01588         }
01589         
01590       //~ if(realscc) // be aware: "else" statement is NOT correct at this point, as realscc-value is changed in the above if-clause
01591         //~ {
01592     //~ // cout<<endl<<"found ycless SCC with root "<<state<<", consisting of the following states:"<<endl<<"begin"<<endl;
01593     //~ rRoots.Insert(state);
01594         //~ }
01595         
01596       //create SCC
01597       StateSet Scc;
01598       bool purelyUnMarked=true;
01599       // begin
01600       // repeat
01601       while(true)
01602         {// begin
01603     // pop x from top of STACK and print x;
01604     Idx top=rSTACK.top();
01605     if(realscc) // things outside the "if(realscc)"-clause have to be done in any case!
01606             {
01607         // cout<<top;
01608         Scc.Insert(top);
01609           if(rGen.ExistsMarkedState(top)) purelyUnMarked=false;
01610             }
01611     rStackStates.Erase(top);
01612     rSTACK.pop();
01613         
01614     // until x=state;
01615     if(top==state)
01616       {
01617         // print "end of SCC", insert SCC into SCCset;
01618         if(realscc)
01619     {
01620       // cout<<endl<<"end"<<endl;
01621           if(!purelyUnMarked || UnMarkedOnly)
01622             {
01623               rSccSet.insert(Scc);
01624               rRoots.Insert(state);
01625             }
01626     }
01627         //system("pause");
01628         break;
01629       }
01630     // cout<<", "<<endl;
01631         } //end while
01632     } // end if
01633 }
01634 
01635 // YclessScc(Generator,Yc-events, SccSet, Roots)
01636 // -> api using SearchYclessScc() from above.
01637 bool YclessScc(
01638   const Generator& rGen,
01639   const EventSet& rYc,
01640   std::set<StateSet>& rSccSet,
01641   StateSet& rRoots)
01642 {
01643   FD_DF("YclessScc(" << rGen.Name() << ")");
01644 
01645   // inititalize results:
01646   rRoots.Clear();
01647   rSccSet.clear();
01648   // initialize counter for depthfirstnumbers(DFN):
01649   int count=1;
01650 
01651   // initialize stack of states (state indeces):
01652   std::stack<Idx> STACK;
01653   // due to lack of STACK-iterator: initialize set of states that are on STACK:
01654   StateSet StackStates = StateSet();
01655 
01656   // initialize set of states to be examined:
01657   StateSet  NewStates=rGen.AccessibleSet();
01658 
01659   // initialize map of state indeces to their DFN:
01660   std::map<const Idx, int> DFN;
01661   // initialize map of state indeces to their LOWLINK:
01662   std::map<const Idx, int> LOWLINK;
01663 
01664   // figure initial state:
01665   Idx InitState = *rGen.InitStatesBegin();
01666   // start recursive depth-first search for Scc's:
01667   while(!NewStates.Empty()) {
01668     // the following 'if' isn't necessary, but provokes search begin at initial state of rGen
01669     if(NewStates.Exists(InitState)) {
01670       SearchYclessScc(InitState, count, rGen, rYc, false, NewStates, STACK, StackStates, DFN, LOWLINK, rSccSet, rRoots);
01671     } else {
01672       SearchYclessScc(*NewStates.Begin(), count, rGen, rYc, false, NewStates, STACK, StackStates, DFN, LOWLINK, rSccSet, rRoots);
01673     }
01674   }
01675   
01676   return !rSccSet.empty();
01677 }
01678 
01679 // YclessUnMarkedScc(Generator,Yc-events, SccSet, Roots)
01680 // -> api using SearchYclessScc() from above.
01681 bool YclessUnmarkedScc(
01682   const Generator& rGen,
01683   const EventSet& rYc,
01684   std::set<StateSet>& rSccSet,
01685   StateSet& rRoots)
01686 {
01687   FD_DF("YclessScc(" << rGen.Name() << ")");
01688 
01689   // inititalize results:
01690   rRoots.Clear();
01691   rSccSet.clear();
01692   // initialize counter for depthfirstnumbers(DFN):
01693   int count=1;
01694 
01695   // initialize stack of states (state indeces):
01696   std::stack<Idx> STACK;
01697   // due to lack of STACK-iterator: initialize set of states that are on STACK:
01698   StateSet StackStates = StateSet();
01699 
01700   // initialize set of states to be examined:
01701   StateSet  NewStates=rGen.AccessibleSet()-rGen.MarkedStates();
01702 
01703   // initialize map of state indeces to their DFN:
01704   std::map<const Idx, int> DFN;
01705   // initialize map of state indeces to their LOWLINK:
01706   std::map<const Idx, int> LOWLINK;
01707 
01708   // figure initial state:
01709   Idx InitState = *rGen.InitStatesBegin();
01710   // start recursive depth-first search for Scc's:
01711   while(!NewStates.Empty()) {
01712     // the following 'if' isn't necessary, but provokes search begin at initial state of rGen
01713     if(NewStates.Exists(InitState)) {
01714       SearchYclessScc(InitState, count, rGen, rYc, true, NewStates, STACK, StackStates, DFN, LOWLINK, rSccSet, rRoots);
01715     } else {
01716       SearchYclessScc(*NewStates.Begin(), count, rGen, rYc, true, NewStates, STACK, StackStates, DFN, LOWLINK, rSccSet, rRoots);
01717     }
01718   }
01719   
01720   return !rSccSet.empty();
01721 }
01722 
01723 
01724 // YclessScc(rGen,rYc,rSccSet)
01725 // -> api using YclessScc() from above.
01726 bool YclessScc(
01727   const Generator& rGen,
01728   const EventSet& rYc,
01729   std::set<StateSet>& rSccSet)
01730 {
01731   FD_DF("YclessScc(" << rGen.Name() << ")");
01732 
01733   // inititalize result:
01734   rSccSet.clear();
01735   
01736   StateSet Roots;
01737   return YclessScc(rGen,rYc,rSccSet,Roots);
01738 }
01739 
01740 // IsYcLive(rGen,rYc)
01741 bool IsYcLive(
01742   const Generator& rGen,
01743   const EventSet& rYc)
01744 {
01745   FD_DF("IsYcLive(" << rGen.Name() << ")");
01746 
01747   std::set<StateSet> rSccSet;
01748   
01749   // Generator is YcLive if no YcLessScc is found
01750   YclessScc(rGen,rYc,rSccSet);
01751   return rSccSet.size()==0;
01752 }
01753 
01754 // WriteStateSets(rStateSets)
01755 // Write set of StateSet's to console.
01756 void WriteStateSets(
01757   const std::set<StateSet>& rStateSets)
01758 {
01759   FD_DF("WriteStateSets()");
01760   std::cout<<std::endl;
01761   if(rStateSets.empty()) {
01762     std::cout<<"WriteStateSets: Set of state sets is empty."<<std::endl;
01763     FD_DF("WriteStateSets: Set of state sets is empty.");
01764     return;
01765   }
01766   std::cout<<">WriteStateSets: Set of state sets begin:"<< std::endl;
01767   std::set<StateSet>::iterator StateSetit = rStateSets.begin();
01768   std::set<StateSet>::iterator StateSetit_end = rStateSets.end();
01769   for (; StateSetit != StateSetit_end; ++StateSetit) {
01770     std::cout<<std::endl<<"  >> State set begin:"<< std::endl;
01771     StateSet::Iterator sit = StateSetit->Begin();
01772     StateSet::Iterator sit_end = StateSetit->End();
01773     for (; sit != sit_end; ++sit) {
01774       std::cout<<"  >> "<<*sit<<std::endl;
01775     }
01776     std::cout<<"  >> State set end."<< std::endl;
01777   }  
01778   std::cout<<std::endl<<">WriteStateSets: Set of state sets end."<<std::endl;
01779 }
01780 
01781 // WriteStateSets(rGen,rStateSets)
01782 // Write set of StateSet's to console.
01783 // Use rGen for symbolic state names
01784 void WriteStateSets(
01785   const Generator& rGen,
01786   const std::set<StateSet>& rStateSets)
01787 {
01788   FD_DF("WriteStateSets()");
01789   std::cout<<std::endl;
01790   if(rStateSets.empty()) {
01791     std::cout<<"WriteStateSets: Set of state sets is empty."<<std::endl;
01792     FD_DF("WriteStateSets: Set of state sets is empty.");
01793     return;
01794   }
01795   std::cout<<">WriteStateSets: Set of state sets begin:"<< std::endl;
01796   std::set<StateSet>::iterator StateSetit = rStateSets.begin();
01797   std::set<StateSet>::iterator StateSetit_end = rStateSets.end();
01798   for (; StateSetit != StateSetit_end; ++StateSetit) {
01799     std::cout<<std::endl<<"  >> State set begin:"<< std::endl;
01800     std::cout<<"  "<<rGen.StateSetToString(*StateSetit)<<std::endl;
01801     std::cout<<"  >> State set end."<< std::endl;
01802   }  
01803   std::cout<<std::endl<<">WriteStateSets: Set of state sets end."<<std::endl;
01804 }
01805 
01806 // SccEntries(rGen,rSccSet,rEntryStates,rEntryTransSet)
01807 void SccEntries(
01808   const Generator& rGen,
01809   const std::set<StateSet>& rSccSet,
01810   StateSet& rEntryStates,
01811   TransSetX2EvX1& rEntryTransSet) {
01812             
01813   FD_DF("SccEntries(...)");
01814 
01815   // prepare results:
01816   rEntryStates.Clear();
01817   rEntryTransSet.Clear();
01818   
01819   //extract all transitions sorted by target state X2
01820   TransSetX2EvX1 trel;
01821   rGen.TransRel(trel);
01822   FD_DF("SccEntries: Entry states of all SCCs:");
01823 
01824   //loop through all SCCs:
01825   std::set<StateSet>::iterator sccit = rSccSet.begin();
01826   std::set<StateSet>::iterator sccit_end = rSccSet.end();
01827   for (int i=0; sccit != sccit_end; ++sccit, i++) {
01828     FD_DF("SccEntries: SCC " << i << " begin:");
01829     //loop through all states:
01830     StateSet::Iterator sit = sccit->Begin();
01831     StateSet::Iterator sit_end = sccit->End();
01832     for (; sit != sit_end; ++sit) {
01833       //check if sit is initial state:
01834       if(rGen.ExistsInitState(*sit)) {
01835         rEntryStates.Insert(*sit);
01836       }        
01837       //loop through all transitions with target state X2=sit:
01838       TransSetX2EvX1::Iterator tit=trel.BeginByX2(*sit);
01839       TransSetX2EvX1::Iterator tit_end=trel.EndByX2(*sit);
01840       for(;tit!=tit_end;tit++) {
01841         //if sit is successor of a state X1 that is element of a SCC different
01842         //from the current SCC "StateSetit" and if sit has not been added to
01843         //rEntryStates up to now, then add sit to EntryStates:
01844         if(!sccit->Exists(tit->X1)) {
01845           // insert entry transition:
01846           rEntryTransSet.Insert(*tit);
01847           // if new, insert entry state:
01848           if(!rEntryStates.Exists(*sit)) {
01849             // Perk: check if Insert returns false anyway if element already
01850             // existed before. if so, then write:
01851             // if(rEntryStates.Insert(*sit)) FD_DF("SccEntries: Entry state:" <<*sit);
01852             FD_DF("SccEntries: Entry state:" <<*sit);
01853             rEntryStates.Insert(*sit);
01854           }
01855         }
01856       }
01857     }
01858     FD_DF("SccEntries: SCC " << i << " end:");
01859   }
01860   FD_DF("SccEntries: done");
01861 }
01862 
01863 // CloneScc(rGen,rScc,rSccSet,rEntryState,rEntryStates,rEntryTransSet)
01864 void CloneScc(
01865   Generator& rGen, 
01866   const StateSet& rScc, 
01867   std::set<StateSet>& rSccSet,
01868   const Idx EntryState, 
01869   StateSet& rEntryStates, 
01870   TransSetX2EvX1& rEntryTransSet)
01871 {
01872   FD_DF("CloneScc(...)");
01873   // initialize map from original SCC-states to their clones:
01874   std::map<const Idx, Idx> clone;
01875   // initialize clone-SCC:
01876   StateSet CloneScc;
01877   // clone SCC-states:
01878   StateSet::Iterator sit=rScc.Begin();
01879   StateSet::Iterator sit_end=rScc.End();
01880   for(;sit!=sit_end;sit++) {
01881     // if sit is marked, also mark its clone
01882     if(rGen.ExistsMarkedState(*sit)) { 
01883       clone[*sit]=rGen.InsMarkedState();
01884       CloneScc.Insert(clone[*sit]);
01885       // cout<<"marked state "<<clone[*sit]<<" of "<<*sit<<" inserted.";
01886     } 
01887     // or else insert unmarked state
01888     else {
01889       clone[*sit]=rGen.InsState();
01890       CloneScc.Insert(clone[*sit]);
01891       // cout<<"unmarked state "<<clone[*sit]<<" of "<<*sit<<" inserted.";
01892     }
01893   }
01894   // add clone of SCC to set of all SCCs:
01895   rSccSet.insert(CloneScc);
01896   // clone all transitions:
01897   sit=rScc.Begin();
01898   for(;sit!=sit_end;sit++) {
01899     TransSet::Iterator tit=rGen.TransRelBegin(*sit);
01900     TransSet::Iterator tit_end=rGen.TransRelEnd(*sit);
01901     for(;tit!=tit_end;tit++) {
01902       // clone all transitions within SCC:
01903       if(rScc.Exists(tit->X2)) {
01904         rGen.SetTransition(clone[*sit],tit->Ev,clone[tit->X2]);
01905       }
01906       //...and transitions leaving the SC: 
01907       else {
01908         rGen.SetTransition(clone[*sit],tit->Ev,tit->X2);
01909         //**** added 06.09.2007:
01910         // If this cloned transition leads to an entry state of
01911         // some other SCC, then  it is a new entry transition:
01912         if(rEntryStates.Exists(tit->X2)) {
01913           rEntryTransSet.Insert(clone[*sit],tit->Ev,tit->X2);
01914         }
01915         //****
01916       }
01917     }
01918   }
01919   // move the head of all entry transitions leading to EntryState to the clone of EntryState:
01920   TransSet TransToClear, EntryTransToInsert;
01921   TransSetX2EvX1::Iterator tit=rEntryTransSet.BeginByX2(EntryState);
01922   TransSetX2EvX1::Iterator tit_end=rEntryTransSet.EndByX2(EntryState);
01923   for(;tit!=tit_end;tit++) {
01924   //    cout<<endl<<"Moving entryTransition "<<"("<<tit->X1<<","<<rGen.EventName(tit->Ev)<<","<<tit->X2<<")";
01925   //    cout<<" to target state "<<clone[EntryState];
01926     rGen.SetTransition(tit->X1,tit->Ev,clone[EntryState]);
01927     //prebook new moved transition to be inserted in rEntryTransSet:
01928     EntryTransToInsert.Insert(tit->X1,tit->Ev,clone[EntryState]);
01929     //prebook transitions to former entry state to clear in rGen and rEntryTransSet:
01930     TransToClear.Insert(*tit);
01931   }
01932   //clear former transitions in rGen and rEntryTransSet:
01933   TransSet::Iterator tit2=TransToClear.Begin();
01934   TransSet::Iterator tit2_end=TransToClear.End();
01935   for(;tit2!=tit2_end;tit2++) {
01936     rGen.ClrTransition(*tit2);
01937     //erase transitions to former entry state from rEntryTransSet:
01938     rEntryTransSet.Erase(*tit2);
01939   }
01940   // update rEntryTransSet with new moved entry transitions:
01941   TransSet::Iterator tit3=EntryTransToInsert.Begin();
01942   TransSet::Iterator tit3_end=EntryTransToInsert.End();
01943   for(;tit3!=tit3_end;tit3++) {
01944     //insert new moved transitions in rEntryTransSet:
01945     rEntryTransSet.Insert(*tit3);
01946   }
01947   //update rEntryStateSet:
01948   rEntryStates.Erase(EntryState); // erase former ambiguous entry state
01949   rEntryStates.Insert(clone[EntryState]); // insert unique entry state of cloned SCC
01950 }
01951 
01952 // CloneUnMarkedScc(rGen,rScc,rSccSet,rEntryState,rEntryStates,rEntryTransSet)
01953 void CloneUnMarkedScc(
01954   Generator& rGen, 
01955   const StateSet& rScc,
01956   const Idx EntryState, 
01957   const StateSet& rEntryStates, 
01958   TransSetX2EvX1& rEntryTransSet)
01959 {
01960   FD_DF("CloneUnMarkedScc(...)");
01961   // initialize map from original SCC-states to their clones:
01962   std::map<const Idx, Idx> clone;
01963   // initialize clone-SCC:
01964   StateSet CloneScc;
01965   // clone all SCC-states but EntryState:
01966   StateSet::Iterator sit=rScc.Begin();
01967   StateSet::Iterator sit_end=rScc.End();
01968   for(;sit!=sit_end;sit++) {
01969       if(*sit != EntryState) {
01970          clone[*sit]=rGen.InsState();
01971          CloneScc.Insert(clone[*sit]);
01972         }
01973       else clone[*sit]=*sit; // entry state is not cloned
01974       
01975     }
01976   
01977   //*** Think about this:
01978   // // add clone of SCC to set of all SCCs:
01979   // rSccSet.insert(CloneScc);
01980   //***
01981     
01982   // clone all transitions:
01983   TransSet TransToClear;
01984   sit=rScc.Begin();
01985   bool isEntryState=false;
01986   TransSet::Iterator tit,tit_end;
01987   for(;sit!=sit_end;sit++) {
01988     isEntryState=(*sit==EntryState);
01989     tit=rGen.TransRelBegin(*sit);
01990     tit_end=rGen.TransRelEnd(*sit);
01991     for(;tit!=tit_end;tit++) {
01992       // clone all transitions within SCC:
01993       if(rScc.Exists(tit->X2)) {
01994         rGen.SetTransition(clone[*sit],tit->Ev,clone[tit->X2]);
01995         // if transition starts at entry state, only keep the clone transition
01996         if(isEntryState) {
01997           // prebook this transition to be cleared
01998           TransToClear.Insert(*tit);
01999         }
02000       }
02001       //...and transitions leaving the SCC:
02002       else {
02003         rGen.SetTransition(clone[*sit],tit->Ev,tit->X2);
02004         //**** added 06.09.2007:
02005         // If this cloned transition leads to an entry state of
02006         // some other SCC, then  it is a new entry transition:
02007         if(rEntryStates.Exists(tit->X2)) {
02008           rEntryTransSet.Insert(clone[*sit],tit->Ev,tit->X2);
02009         }
02010         //****
02011       }
02012     }
02013   }
02014   
02015   // clear prebooked transitions
02016   tit=TransToClear.Begin();
02017   tit_end=TransToClear.End();
02018   for(;tit!=tit_end;tit++) {
02019     rGen.ClrTransition(*tit);
02020   }
02021 
02022 }
02023 //============================
02024 
02025 
02026 
02027 // YcAcyclic(rGen,rYc,rResGen)
02028 void YcAcyclic(
02029   const Generator& rGen,
02030   const EventSet& rYc,
02031   Generator& rResGen)
02032 {
02033   FD_DF("YcAcyclic: Statesize before: "<<rGen.Size()<<" - starting...");
02034   // initialize set of ycless strongly connected components (SCCs):
02035   std::set<StateSet> SccSet,UnMarkedSccSet;
02036   // initialize set of all states that are member or root or entry state of some SCC:
02037   StateSet Scc,Roots,EntryStates,notRoots,UnMarkedRoots;
02038   // initialize set of transitions that enter some SCC from a different SCC,
02039   // sorted by target states X2 (which are entry states):
02040   TransSetX2EvX1 EntryTransSet;
02041   // take rGen as first candidate:
02042   rResGen=rGen;
02043   // counter for below while loop:
02044   // int i=0;
02045 
02046   while(true) {
02047     //++i;
02048     // check for SCCs and return if there are none -> ResGen is the result.
02049     // cout<<endl<<"Round "<<i<<": Searching for remaining Yc-less SCCs...";
02050     if(!YclessScc(rResGen,rYc,SccSet,Roots)) {
02051        //time_t *t2;
02052        //time(t2);
02053        //cout<<"...finished in "<<difftime(*t2, *t1)<<" seconds.";
02054         //rResGen.DotWrite("tmp_YcAcyclic_res");
02055       FD_DF("YcAcyclic: Statesize of result: "<<rResGen.Size());
02056 //        cout<<". Statemin...";
02057 //        Generator tmp;
02058 //        StateMin(rResGen,tmp);
02059 //        cout<<"done. New Statesize:"<<tmp.Size();
02060 //        tmp.ClrStateNames();
02061 //        rResGen=tmp;
02062 //        tmp.Clear();
02063         //rResGen.Write("tmp_YcAcyclic.gen");
02064           return;
02065         }
02066     //cout<<endl<<"...found "<<SCCset.size()<<" Yc-less SCCs: computing entry states...";
02067 //    cout<<"Found following Yc-less SCCs:"<<endl;
02068 //    WriteStateSets(SCCset);
02069 //    system("pause");
02070     // else figure entry states and entry transitions of the SCCs
02071     SccEntries(rResGen,SccSet,EntryStates,EntryTransSet);
02072     
02073     // root states are kept as entry states of the original SCCs, for all other
02074     // entry states clone SCCs:
02075     notRoots=EntryStates - Roots;
02076     //cout<<"...found "<<notRoots.Size()<<" entry states that are not roots. Start cloning SCCs..."<<endl;
02077 //    cout<<endl<<"EntryStates before cloning:"<<endl;
02078 //    EntryStates.DWrite();
02079 //    cout<<endl<<"Roots before cloning:"<<endl;
02080 //    Roots.DWrite();
02081 //    cout<<endl<<"notRoots before cloning:"<<endl;
02082 //    notRoots.DWrite();
02083 
02084     StateSet::Iterator sit=notRoots.Begin();
02085     StateSet::Iterator sit_end=notRoots.End();
02086     for(;sit!=sit_end;sit++)
02087         {
02088         // figure SCC with entry state sit:
02089     std::set<StateSet>::iterator sccit = SccSet.begin();
02090     std::set<StateSet>::iterator sccit_end = SccSet.end();
02091         for (; sccit != sccit_end; ++sccit)
02092             {
02093             if(sccit->Exists(*sit))
02094                 {
02095                 Scc=*sccit;
02096                 break;
02097                 }
02098             }
02099         // clone this SCC (and add clone to SCCset):
02100 //        cout<<"cloning SCCC:"<<endl;
02101 //        SCC.DWrite();
02102         CloneScc(rResGen,Scc,SccSet,*sit,EntryStates,EntryTransSet);
02103 //        cout<<endl<<"New set of SCCs:"<<endl;
02104 //        WriteStateSets(SccSet);
02105         }
02106     //cout<<endl<<"...done. Identifying unique entry states...";
02107 //    rResGen.Write("tmp_YcAcyclic_step.gen");
02108 //    rResGen.DotWrite("tmp_YcAcyclic_step");
02109 //    ++i;
02110 //    cout<<endl<<"Printed intermediate result "<<i<<"."<<endl;
02111 //    system("pause");
02112 
02113     // Now, all SCCs have one unique entry state.
02114     // If some SCC contains a sub-SCC that a) includes the entry
02115     // state of the whole SCC and b) consists of only unmarked
02116     // states, then this sub-SCC has to be copied to resolve the
02117     // ambiguity.
02118     if( !(  ((rResGen.States()-rResGen.MarkedStates())*EntryStates).Empty()  ) ) {
02119         // find possible unmarked sub-SCCs including EntryState
02120         YclessUnmarkedScc(rResGen,rYc,UnMarkedSccSet,UnMarkedRoots);
02121         std::set<StateSet>::iterator sccit = UnMarkedSccSet.begin();
02122         std::set<StateSet>::iterator sccit_end = UnMarkedSccSet.end();
02123         for (; sccit != sccit_end; ++sccit) {
02124             // check if this unmarked sub-SCC includes an EntryState; if so: clone it
02125             if(  !( ((*sccit)*EntryStates).Empty() )  ) {
02126                  Idx EntryState=*(((*sccit)*EntryStates).Begin());
02127                  CloneUnMarkedScc(rResGen,*sccit,EntryState,EntryStates,EntryTransSet);
02128                 }
02129         }
02130     }
02131         
02132     
02133     
02134     //"Back transitions" leading
02135     // from a SCC to its own entry state have to be cancelled,
02136     // if they are not Yc-transitions:
02137 
02138     // 2) loop through all SCCs and find Ycless back transitions:
02139     TransSet TransToClear;
02140     std::set<StateSet>::iterator sccit = SccSet.begin();
02141     std::set<StateSet>::iterator sccit_end = SccSet.end();
02142     //cout<<endl<<"Determining non-yc-backtransitions...";
02143     for (; sccit != sccit_end; ++sccit)
02144         {
02145         //loop through all states:
02146         StateSet::Iterator sit = sccit->Begin();
02147         StateSet::Iterator sit_end = sccit->End();
02148         for (; sit != sit_end; ++sit)
02149             {
02150             //cout<<endl<<"looping state "<<*sit<<endl;
02151             // loop through all transitions:
02152             TransSet::Iterator tit=rResGen.TransRelBegin(*sit);
02153             TransSet::Iterator tit_end=rResGen.TransRelEnd(*sit);
02154             for(;tit!=tit_end;tit++)
02155                 {
02156                 // Check if tit leads back to entry state of current SCC
02157                 // and if it is not a Yc-transition:
02158                 if(sccit->Exists(tit->X2) && EntryStates.Exists(tit->X2)
02159                    &&!rYc.Exists(tit->Ev))
02160                     {
02161                     //cout<<" - Trans to clear: "<<tit->Ev<<endl;
02162                     TransToClear.Insert(*tit);
02163                     }
02164                 }
02165             }
02166         }
02167     //cout<<endl<<"...found "<<TransToClear.Size()<<" transitions. Deleting these transitions...";
02168     // 3) Clear back transitions:
02169     TransSet::Iterator tit=TransToClear.Begin();
02170     TransSet::Iterator tit_end=TransToClear.End();
02171     for(;tit!=tit_end;tit++)
02172         {
02173         //cout<<"clearing transition ("<<tit->X1<<","<<rResGen.EventName(tit->Ev)<<","<<tit->X2<<")"<<endl;
02174         rResGen.ClrTransition(*tit);
02175         }
02176         
02177 //    ++i;
02178 //    rResGen.Write("tmp_YcAcyclic_step.gen");
02179 //    rResGen.DotWrite("tmp_YcAcyclic_step");
02180 //    cout<<endl<<"Printed intermediate result "<<i<<"."<<endl;
02181 //    system("pause");
02182 //    cout<<endl<<"...transitions deletetd, next round!";
02183 //     cout<<endl<<"state size of current intermediate result: "<<rResGen.Size();
02184      //cout<<endl<<". Press enter to start statemin."<<endl;
02185      //string anykey;
02186      //getline( cin, anykey );
02187 
02188 //     cout<<". Statemin...";
02189 //     Generator tmp;
02190 //     StateMin(rResGen,tmp);
02191 //     cout<<"done. New Statesize:"<<tmp.Size();
02192 //     rResGen=tmp;
02193 //     tmp.Clear();
02194 
02195 //    system("pause");
02196     } //end while(true): resulting generator might contain SCCs within the
02197       // SCCs that have been "broken" in this step -> continue while-loop.
02198 }
02199 
02200 //**********************************************************
02201 //******************** hio synthesis ************************
02202 //**********************************************************
02203 
02204 // ConstrSynth_Beta(rPlant,rYp,rUp,rOpConstr)
02205 void ConstrSynth_Beta(
02206         Generator& rPlant,
02207   const EventSet& rYp,
02208   const EventSet& rUp,
02209   const Generator& rLocConstr,
02210   Generator& rOpConstraint) {
02211   
02212     FD_DF("ConstrSynth_Beta(...)");
02213   
02214   // helper
02215   Generator tmpGen;
02216   EventSet sigmap=rYp+rUp;
02217   
02218   //prepare rsult:
02219   rOpConstraint.Clear();
02220   
02221   // respect optional local constraints
02222   Parallel(rPlant,rLocConstr,rOpConstraint);
02223   
02224   // calculate YpAcyclic sublanguage:
02225   YcAcyclic(rOpConstraint,rYp,tmpGen);
02226   rOpConstraint.Clear();
02227   
02228   // compute normal, complete, controllable and nonblocking sublanguage
02229   // note: tmpGen has role of spec
02230   NormalCompleteSynthNB(rPlant,rUp,sigmap,tmpGen,rOpConstraint);
02231   tmpGen.Clear();
02232   
02233   // project to P-Alphabet
02234   Project(rOpConstraint,sigmap,tmpGen);
02235   rOpConstraint.Clear();
02236   
02237   // minimize state space
02238   StateMin(tmpGen,tmpGen);
02239   tmpGen.ClearStateNames();
02240   
02241   // eneable symbolic state names for error states
02242   tmpGen.StateNamesEnabled(true);
02243   rOpConstraint.StateNamesEnabled(true);
02244   // make YP free in OpConstr
02245   HioFreeInput(tmpGen, rYp, rUp, rOpConstraint, "errUp","errYp");
02246 
02247   rOpConstraint.Name("ConstrSynth_Beta("+rPlant.Name()+")");
02248   
02249   return;
02250   }
02251 
02252 // HioSynthUnchecked(rPlant,rSpec,rConstr,rLocConstr,rYc,rUc,rYp,rUp,rYel,rUel,rController)
02253 void HioSynthUnchecked(
02254   const Generator& rPlant,
02255   const Generator& rSpec,
02256   const Generator& rExtConstr,
02257   const Generator& rLocConstr,
02258   const EventSet& rYc,
02259   const EventSet& rUc, 
02260   const EventSet& rYp,
02261   const EventSet& rUp, 
02262   const EventSet& rYel,
02263   const EventSet& rUel,
02264   Generator& rController)
02265 { 
02266   FD_DF("HioSynth(...)");
02267   //prepare rsult:
02268   rController.Clear();
02269   //make copy of plant, spec for modifications
02270   Generator plant,spec;
02271   plant = rPlant;
02272   spec = rSpec;
02273   
02274   //create necessary eventsets:
02275   EventSet sigmacp;
02276   sigmacp.SetUnion(rUc + rYc + rUp + rYp);
02277   EventSet sigmace;
02278   sigmace.SetUnion(rUc + rYc + rUel + rYel);
02279   
02280   EventSet allsigma;
02281   allsigma.SetUnion(rPlant.Alphabet());
02282   allsigma.SetUnion(rSpec.Alphabet());
02283   
02284   EventSet controllable, wait;
02285   controllable.SetUnion(rUp);
02286   controllable.SetUnion(rYc);
02287 
02288   //make alphabets of plant and spec match:
02289   InvProject(plant,allsigma);
02290   InvProject(spec,allsigma);
02291   
02292   // FD_DF("******************** actual plant: composition with external constraints");
02293   
02294   // generate plant under constraint:
02295   Parallel(plant,rExtConstr,plant);
02296   //plant.Write("tmp_cplant.gen");
02297   
02298   //FD_DF("******************** mininmal hio structure, composition with plant");
02299   Generator minhio;
02300   minhio = HioSortCL(rYc,rUc,rYp,rUp,rYel,rUel);
02301   //minhio.Write("tmp_minhio.gen");
02302   
02303   // generate plant in hio structure:
02304   Parallel(plant,minhio,plant);
02305   plant.ClearStateNames();
02306   //plant.Write("tmp_hiocplant.gen");
02307   
02308   //FD_DF("******************** composition plant-specification: tmp_plantspec.gen ");
02309   
02310   // composition of plant, I/O sorting, constraint and specification:
02311   Generator plantspec;
02312   Parallel(plant,spec,plantspec);
02313   //plantspec.Write("tmp_plantspec.gen");
02314   plantspec.ClearStateNames();
02315   FD_DF("Size of plantspec: "<<plantspec.Size()<<" - Statemin...");
02316   StateMin(plantspec,plantspec);
02317   FD_DF("done. New Statesize: "<<plantspec.Size()<<".");
02318   plantspec.ClearStateNames();
02319     //plantspec.Write("results/tmp_plantspec.gen");
02320   FD_DF("******************** computing YcAcyclic(plantspec):");
02321   
02322   // calculate YcAcyclic sublanguage of plantspec:
02323   Generator yclifeplantspec;
02324   YcAcyclic(plantspec,rYc,yclifeplantspec);
02325   yclifeplantspec.ClearStateNames();
02326   //yclifeplantspec.Write("tmp_YcAcyclic.gen");
02327   
02328   //FD_DF("******************** actual spec: composition yclifeplantspec||minhio||locconstr (tmp_actualspec.gen)");
02329   //generate plantspec with closed-loop I/O sorting:
02330   Parallel(yclifeplantspec,minhio,plantspec);
02331   yclifeplantspec.Clear();
02332   //add local constraints to plantspec: the result is the actual spec for synthesis
02333   Parallel(plantspec,rLocConstr,plantspec);
02334   plantspec.ClearStateNames();
02335   plantspec.Name("actualspec");
02336   //plantspec.Write("tmp_actualspec.gen");
02337   
02338   //FD_DF("******************** closed loop synthesis: tmp_closedloop.gen/.dot");
02339   
02340   // compute normal, complete and controllable sublangugae of actualspec w.r.t. plant under constraints (cplant):
02341   Generator loop;
02342   NormalCompleteSynthNB(plant,controllable,sigmacp,plantspec,loop);
02343   plantspec.Clear();
02344   //loop.Write("tmp_closedloop.gen");
02345   
02346   FD_DF("size of closed loop before StateMin: "<<loop.Size()<<", starting StateMin...");
02347   StateMin(loop,loop);
02348   FD_DF("...size of closed loop after StateMin (tmp_closedloop.gen): "<<loop.Size());
02349     //std::cout<<"ClosedLoop.IsTrim: "<<loop.IsTrim();
02350   loop.ClearStateNames();
02351   // loop.Write("tmp_closedloop.gen");
02352   FD_DF("********* IsYcLive(closed loop): "<<IsYcLive(loop,rYc));
02353   plant.Clear();
02354   
02355   //calculate external closedloop:
02356   FD_DF("******************** external closed loop: tmp_extloop.gen");
02357   Generator extloop;
02358   Project(loop,sigmace,extloop);
02359   FD_DF("size of external closed loop: "<<extloop.Size());
02360   
02361   // // recheck if specification is met:
02362   // if(LanguageInclusion(extloop,rSpec)) {
02363     // FD_DF("External closed loop meets specification.");
02364       // } // Perk: change below to LanguageInclusion with reverse order of parameters
02365       // // and move into above bracket.
02366   // if(LanguageEquality(extloop,rSpec)) {
02367     // FD_DF("External closed loop EQUALS specification.");
02368       // }
02369   
02370   extloop.ClearStateNames();
02371   //extloop.Write("tmp_extloop.gen");
02372   
02373   FD_DF("******************** project closed loop: tmp_controller.gen");
02374   
02375   Generator controller;
02376   Project(loop,sigmacp,controller);
02377   loop.Clear();
02378   controller.ClearStateNames();
02379   //controller.Write("tmp_controller.gen");
02380   
02381   // extend to io-controller: result
02382   HioFreeInput(controller, rYp, rUp, rController, "errUp","errYp");
02383   controller.Clear();
02384   FD_DF("size of marked IO controller: "<<rController.Size()<<". PrefixClosure, StateMin...");
02385   
02386   // the following procedure erases all marking information to reduce the result's state space! This step is unproblematic as long as the specification
02387   // 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
02388   // wether this step is correct or should be omitted .
02389   if(!(rSpec.AccessibleSet()<=rSpec.MarkedStates())) {
02390   FD_WARN("Careful: marking information of the specification has been erased from the resulting controller.");
02391   }
02392   PrefixClosure(rController);
02393   StateMin(rController,rController);
02394   FD_DF("...size of prefix-closed IO controller after StateMin: "<<rController.Size());
02395   rController.ClearStateNames();
02396   rController.Name("HioSynth("+rPlant.Name()+","+rSpec.Name()+")");
02397   FD_DF("IO controller synthesis done. ******************** " );
02398 }
02399 
02400 // HioSynth(rPlant,rSpec,rConstr,rLocConstr,rYc,rUc,rYp,rUp,rYel,rUel,rController)
02401 void HioSynth(
02402   const Generator& rPlant,
02403   const Generator& rSpec,
02404   const Generator& rExtConstr,
02405   const Generator& rLocConstr,
02406   const EventSet& rYc,
02407   const EventSet& rUc, 
02408   const EventSet& rYp,
02409   const EventSet& rUp, 
02410   const EventSet& rYel,
02411   const EventSet& rUel,
02412   Generator& rController)
02413 { 
02414   
02415   rController.Clear();
02416   
02417   #ifdef FAUDES_CHECKED
02418   // exception on empty alphabets
02419   if (rYc.Empty()){
02420    std::stringstream errstr;
02421    errstr << "Empty Yc alphabet\n";
02422    throw Exception("HioSynth", errstr.str(), 0);
02423   }
02424   if (rUc.Empty()){
02425    std::stringstream errstr;
02426    errstr << "Empty Uc alphabet\n";
02427    throw Exception("HioSynth", errstr.str(), 0);
02428   }
02429   if (rYp.Empty()){
02430    std::stringstream errstr;
02431    errstr << "Empty Yp alphabet\n";
02432    throw Exception("HioSynth", errstr.str(), 0);
02433   }
02434   if (rUp.Empty()){
02435    std::stringstream errstr;
02436    errstr << "Empty Up alphabet\n";
02437    throw Exception("HioSynth", errstr.str(), 0);
02438   }
02439   if (rYel.Empty()){
02440    std::stringstream errstr;
02441    errstr << "Empty Ye alphabet\n";
02442    throw Exception("HioSynth", errstr.str(), 0);
02443   }
02444   if (rUel.Empty()){
02445    std::stringstream errstr;
02446    errstr << "Empty Ue alphabet\n";
02447    throw Exception("HioSynth", errstr.str(), 0);
02448   }
02449   
02450   // create resulting alphabet while checking for disjoint sets
02451   EventSet alphabet,errevents;
02452   // initialize with rYc
02453   alphabet.SetUnion(rYc);
02454   // insert remaining events one by one and check if new
02455   EventSet::Iterator evit;
02456   // rUc
02457   for (evit = rUc.Begin(); evit != rUc.End(); ++evit) {
02458     if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
02459   }
02460   // rYp
02461   for (evit = rYp.Begin(); evit != rYp.End(); ++evit) {
02462     if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
02463   }
02464   // rUp
02465   for (evit = rUp.Begin(); evit != rUp.End(); ++evit) {
02466     if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
02467   }
02468   // rYe
02469   for (evit = rYel.Begin(); evit != rYel.End(); ++evit) {
02470     if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
02471   }
02472   // rUe
02473   for (evit = rUel.Begin(); evit != rUel.End(); ++evit) {
02474     if(!(alphabet.Insert(*evit))) errevents.Insert(*evit);
02475   }
02476   // throw exception on non disjoint alphabets
02477   if (!errevents.Empty()){
02478      std::stringstream errstr;
02479      errstr << "Non-disjoint parameters; ambiguous events:\n" <<errevents.ToString();
02480    throw Exception("HioSynth", errstr.str(), 0);
02481   }
02482   // check alphabet matches:
02483   EventSet plantEvents, specEvents;
02484   plantEvents=rPlant.Alphabet();
02485   specEvents=rSpec.Alphabet();
02486   // plant and spec must share environment alphabet
02487   if (!(plantEvents*specEvents==rYel+rUel)){
02488      std::stringstream errstr;
02489      errstr << "Alphabet mismatch between plant and spec:\n";
02490      errstr << "plant: " << plantEvents.ToString() << "\n";
02491      errstr << "spec: " << specEvents.ToString() << "\n";
02492      errstr << "Yel+Uel:   " << (rYel+rUel).ToString() << "\n";
02493    throw Exception("HioSynth", errstr.str(), 0);  
02494   }
02495   // ExtConstr must relate to spec alphabet
02496   if (!(rExtConstr.Alphabet()<=specEvents)){
02497     std::stringstream errstr;
02498     errstr << "Alphabet mismatch between external constraints and spec.\n";
02499   throw Exception("HioSynth", errstr.str(), 0);
02500   }
02501   // LocConstr must relate to plant alphabet
02502   if (!(rLocConstr.Alphabet()<=plantEvents)){
02503     std::stringstream errstr;
02504     errstr << "Alphabet mismatch between internal constraints and plant.\n";
02505   throw Exception("HioSynth", errstr.str(), 0);
02506   }
02507   
02508   // check I/O plant form of spec (note: plant may be composed group and thus need not be in I/o plant form)
02509   HioPlant spec(rSpec,rYc,rUc,rYel,rUel);
02510   std::string report;
02511   if(!IsHioPlantForm(spec,report)){
02512     std::stringstream errstr;
02513     errstr << "Spec not in HioPlantForm:\n" << report;
02514   throw Exception("HioSynth", errstr.str(), 0);
02515   }
02516   report.clear();
02517   #endif
02518   
02519   // do hio synthesis
02520   HioSynthUnchecked(rPlant,rSpec,rExtConstr,rLocConstr,rYc,rUc,rYp,rUp,rYel,rUel,rController);
02521 }
02522 
02523 // HioSynthMonolithic(rPlant,rSpec,rSc,rSp,rSe,rController)
02524 void HioSynthMonolithic(
02525   const HioPlant& rPlant,
02526   const HioPlant& rSpec,
02527   const HioConstraint& rSc,
02528   const HioConstraint& rSp,
02529   const HioConstraint& rSe,
02530   HioController& rController) {
02531   
02532   rController.Clear();
02533   
02534   #ifdef FAUDES_CHECKED
02535   // check I/O plant form of rPlant (further parameter checks in HioSynth())
02536   // tmp non-const copy of const rPlant
02537   HioPlant plant=rPlant;
02538   std::string report;
02539   if(!IsHioPlantForm(plant,report)){
02540     std::stringstream errstr;
02541     errstr << "Plant not in HioPlantForm:\n" << report;
02542   throw Exception("HioSynthMonolithic", errstr.str(), 0);
02543   }
02544   plant.Clear();
02545   report.clear();
02546   #endif
02547   
02548   // extract alphabets
02549   EventSet yc,uc,yp,up,ye,ue;
02550   yc=rSpec.YpEvents();
02551   uc=rSpec.UpEvents();
02552   yp=rPlant.YpEvents();
02553   up=rPlant.UpEvents();
02554   ye=rSpec.YeEvents();
02555   ue=rSpec.UeEvents();
02556   
02557   // generator for composed external constraints
02558   Generator extConstr;
02559   Parallel(rSc,rSe,extConstr);
02560   
02561   // run HioSynth procedure
02562   HioSynth(rPlant,rSpec,extConstr,rSp,yc,uc,yp,up,ye,ue,rController);
02563   
02564   // set event and state attributes
02565   rController.SetYc(yc);
02566   rController.SetUc(uc);
02567   rController.SetYp(yp);
02568   rController.SetUp(up);
02569   
02570   IsHioControllerForm(rController);
02571 }
02572 
02573 void HioSynthHierarchical(
02574   const HioPlant& rHioShuffle,
02575   const HioEnvironment& rEnvironment,
02576   const HioPlant& rSpec,
02577   const Generator& rIntConstr,
02578   const HioConstraint& rSc,
02579   const HioConstraint& rSl,
02580   HioController& rController) {
02581   
02582   rController.Clear();
02583   
02584   #ifdef FAUDES_CHECKED
02585   // check I/O plant form of rPlant (further parameter checks in HioSynth())
02586   // tmp non-const copy of const rPlant
02587   HioPlant plant=rHioShuffle;
02588   std::string report;
02589   if(!IsHioPlantForm(plant,report)){
02590     std::stringstream errstr;
02591     errstr << "HioShuffle not in HioPlantForm:\n" << report;
02592   throw Exception("HioSynthHierarchical", errstr.str(), 0);
02593   }
02594   plant.Clear();
02595   report.clear();
02596   
02597   // check I/O environment form
02598   // tmp non-const copy of const rEnvironment
02599   HioEnvironment env=rEnvironment;
02600   if(!IsHioEnvironmentForm(env,report)){
02601     std::stringstream errstr;
02602     errstr << "Environment not in HioEnvironmentForm:\n" << report;
02603   throw Exception("HioSynthHierarchical", errstr.str(), 0);
02604   }
02605   env.Clear();
02606   report.clear();
02607   
02608   // check for matching alphabets between ioshuffle, environment and spec
02609   if (!(rHioShuffle.EEvents()==rEnvironment.EEvents())){
02610     std::stringstream errstr;
02611     errstr << "Alphabet mismatch between I/O-shuffle and environment.\n";
02612   throw Exception("HioSynthHierarchical", errstr.str(), 0);
02613   }  
02614   // check for matching alphabets between ioshuffle, environment and spec
02615   if (!(rSpec.EEvents()==rEnvironment.LEvents())){
02616     std::stringstream errstr;
02617     errstr << "Alphabet mismatch between specification and environment.\n";
02618   throw Exception("HioSynthHierarchical", errstr.str(), 0);
02619   }
02620   
02621    //(further parameter checks in HioSynth())
02622    
02623   #endif
02624   // compose ioshuffle and environment
02625   Generator ioShuffParEnv;
02626   Parallel(rHioShuffle,rEnvironment,ioShuffParEnv);
02627   
02628   // extract alphabets
02629   EventSet yc,uc,yp,up,ye,ue;
02630   yc=rSpec.YpEvents();
02631   uc=rSpec.UpEvents();
02632   yp=rHioShuffle.YpEvents();
02633   up=rHioShuffle.UpEvents();
02634   ye=rSpec.YeEvents();
02635   ue=rSpec.UeEvents();
02636   
02637   // generator for composed external constraints
02638   Generator extConstr;
02639   Parallel(rSc,rSl,extConstr);
02640   
02641   // run HioSynth procedure
02642   HioSynth(ioShuffParEnv,rSpec,extConstr,rIntConstr,yc,uc,yp,up,ye,ue,rController); 
02643   
02644   // set event and state attributes
02645   rController.SetYc(yc);
02646   rController.SetUc(uc);
02647   rController.SetYp(yp);
02648   rController.SetUp(up);
02649   
02650   IsHioControllerForm(rController);
02651 }
02652 
02653 // end of hio_functions - below just archive 
02654 
02655 //######################################################
02656 //############ Special versions for HioModule - will soon be obsolete
02657 
02658 //HioShuffle_Musunoi() - Version with hio-parameters
02659 void HioShuffle_Musunoi(
02660   const HioPlant& rPlantA, 
02661   const HioPlant& rPlantB, 
02662   int depth, 
02663   Generator& rIOShuffAB) 
02664 { 
02665   FD_DF("HioShuffle()_Musunoi");
02666 
02667   //Extract alphabets:             
02668   EventSet A,B,SigmaP, Yp, Up, Ye, Ue;
02669   Yp = rPlantA.YpEvents()+rPlantB.YpEvents();
02670   Ye = rPlantA.YeEvents()+rPlantB.YeEvents();
02671   Up = rPlantA.UpEvents()+rPlantB.UpEvents();
02672   Ue = rPlantA.UeEvents()+rPlantB.UeEvents();
02673   A = rPlantA.Alphabet();
02674   B = rPlantB.Alphabet();
02675   
02676 
02677   // parallel composition of plantA and plantB (i.e. shuffle as there are no shared events)
02678   Generator parallel1, parallel2;
02679   Parallel(rPlantA,rPlantB,parallel1);
02680 
02681   // restrict to event pairs [(SigA SigA)*+(SigB SigB)*]*, which results
02682   // in correct I/O sorting L_IO.
02683   Generator EventPairs; // generator of above sorting language
02684   EventPairs.InjectAlphabet(A + B);
02685   Idx state1,state2,state3;
02686   state1=EventPairs.InsInitState("1");
02687   EventPairs.SetMarkedState(state1);
02688   state2=EventPairs.InsMarkedState("2");
02689   state3=EventPairs.InsMarkedState("3");
02690   EventSet::Iterator evit;
02691   for (evit = A.Begin(); evit != A.End(); ++evit) {
02692     EventPairs.SetTransition(state1,*evit,state2);
02693     EventPairs.SetTransition(state2,*evit,state1);
02694   }
02695   for (evit = B.Begin(); evit != B.End(); ++evit) {
02696     EventPairs.SetTransition(state1,*evit,state3);
02697     EventPairs.SetTransition(state3,*evit,state1);
02698   }
02699   Parallel(parallel1,EventPairs,parallel2);
02700 
02701   //restrict to IO-sorting structure with forced alternation:
02702 
02703   // Old Vers before Dez 4 2006: + of whole alphabets
02704   EventSet Ap, Bp, Ae, Be, SigmaE;
02705   
02706   Ap = rPlantA.Alphabet();
02707   Bp = rPlantB.Alphabet();
02708   
02709   Ae = rPlantA.Alphabet();
02710   Be = rPlantB.Alphabet();
02711   
02712   
02713 
02714   //*************************************************************************
02715   //// New Vers: Alternation of YP Events only
02716   //// -> currently leads to normality problems during superposed controller synthesis
02717   SigmaP.SetUnion(Yp);
02718   SigmaP.SetUnion(Up);
02719   Ap.SetIntersection(SigmaP);
02720   Bp.SetIntersection(SigmaP);
02721   
02722   SigmaE.SetUnion(Ye);
02723   SigmaE.SetUnion(Ue);
02724   Ae.SetIntersection(SigmaE);
02725   Be.SetIntersection(SigmaE);
02726   
02727   
02728   //*************************************************************************
02729   Generator AltAB;
02730   Ap.Name("A");
02731   Bp.Name("B");
02732   CheapAltAB(Ap,Bp,depth,AltAB);
02733   // Alt_AB.Write("tmp_Alternation_AB.gen");
02734   Parallel(parallel2, AltAB, parallel1);
02735   //parallel2.Write("tmp_IOS3.gen");
02736   
02737   
02738   
02739   //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
02740   //*** Environment-first policy: If, in some state both, Yp- and Ye events are
02741   //*** active, then cancel all Yp-transitions in this state, as environment has
02742   //*** to be updated first.
02743 
02744   // loop all states
02745   StateSet::Iterator sit = parallel1.StatesBegin();
02746   StateSet::Iterator sit_end = parallel1.StatesEnd();
02747   
02748   for(; sit != sit_end; sit++)
02749   {
02750         // figure active Yp-events and active Ye-events
02751         //std::cout << "End: " << *sit_end <<"...done: " << *sit << std::endl;
02752         EventSet ActiveYe;
02753         EventSet ActiveYp = parallel1.TransRel().ActiveEvents(*sit);
02754         ActiveYe=ActiveYp;
02755         ActiveYe.SetIntersection(Ye);
02756         ActiveYp.SetIntersection(Yp);
02757             
02758         if (!(ActiveYe.Empty())&& !(ActiveYp.Empty()))
02759         {   
02760             TransSet TransToClear;
02761             TransSet::Iterator tit=parallel1.TransRelBegin(*sit);
02762             TransSet::Iterator tit_end=parallel1.TransRelEnd(*sit);
02763             for(;tit!=tit_end;tit++)
02764                 {
02765                 //std::cout << "finding Yp-events to delete... "; 
02766                 if(ActiveYp.Exists(tit->Ev))
02767                     {
02768                     TransToClear.Insert(*tit);
02769                     }
02770                 }
02771             tit=TransToClear.Begin();
02772             tit_end=TransToClear.End();
02773             for(;tit!=tit_end;tit++)
02774             {
02775             //std::cout<<" ...deleting" <<std::endl;
02776             parallel1.ClrTransition(*tit);
02777             }
02778         } 
02779   }  
02780   
02781   //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
02782   
02783   
02784   
02785   // Insert Error Behaviour, i.e. make UP and UE free in (YP,UP)-port of result:
02786   // free UP:
02787           
02788   HioFreeInput(parallel1, Up, Yp, parallel2, "errYp_Ye", "errUp");
02789   //parallel1.Write("tmp_IOS4.gen");
02790   // free UE:
02791   HioFreeInput(parallel2, Ue, Ye, parallel1, "errYp_Ye", "errUe");
02792   //parallel2.Write("tmp_IOS5.gen");
02793 
02794   rIOShuffAB = parallel1;
02795 }
02796 
02797 // HioSynth_Musunoi()
02798 void HioSynth_Musunoi(const Generator& rPlant, const HioPlant& rSpec,
02799     const Generator& rConstr, const Generator& rLocConstr,
02800     const EventSet& rYp,  const EventSet& rUp, 
02801     Generator& rController)
02802     {
02803 EventSet rYc, rUc, rYe, rUe;
02804 rYc = (rSpec.YpEvents());
02805 rUc = (rSpec.UpEvents());
02806 rYe = (rSpec.YeEvents());
02807 rUe = (rSpec.UeEvents());
02808 
02809 
02810 //make copy of plant, spec, constr and alphabets
02811 Generator plant,spec,constr,locconstr;
02812 plant = rPlant;
02813 spec = rSpec;
02814 constr = rConstr;
02815 locconstr = rLocConstr;
02816 
02817 EventSet yc,uc,yp,up,ye,ue;
02818 yc = rYc;
02819 uc = rUc;
02820 yp = rYp;
02821 up = rUp;
02822 ye = rYe;
02823 ue = rUe;
02824 
02825 //create necessary eventsets:
02826 EventSet sigmacp;
02827 sigmacp.SetUnion(rUc + rYc + rUp + rYp);
02828 EventSet sigmace;
02829 sigmace.SetUnion(rUc + rYc + rUe + rYe);
02830 
02831 EventSet allsigma;
02832 allsigma.SetUnion(rPlant.Alphabet());
02833 allsigma.SetUnion(rSpec.Alphabet());
02834 
02835 EventSet controllable;
02836 controllable.SetUnion(up);
02837 controllable.SetUnion(yc);
02838 
02839 //make alphabets of plant and spec match:
02840 InvProject(plant,allsigma);
02841 InvProject(spec,allsigma);
02842 
02843  FD_DF("******************** actual plant: composition with environment constraint: tmp_cplant.gen ");
02844 
02845 // generate plant under constraint:
02846 Generator cplant;
02847 Parallel(plant,constr,cplant);
02848 //cplant.Write("tmp_cplant.gen");
02849 
02850  FD_DF("******************** mininmal hio structure: tmp_minhio.gen, composition with plant: tmp_hioplant.gen ");
02851 Generator minhio;
02852 minhio = HioSortCL(yc,uc,yp,up,ye,ue);
02853 //minhio.Write("tmp_minhio.gen");
02854 
02855 // generate plant in hio structure:
02856 Generator hiocplant;
02857 Parallel(cplant,minhio,hiocplant);
02858 //hiocplant.Write("tmp_hiocplant.gen");
02859 
02860  FD_DF("******************** composition plant-specification: tmp_plantspec.gen ");
02861 
02862 // composition of plant, I/O sorting, constraint and specification:
02863 Generator plantspec,plantspecMin;
02864 Parallel(hiocplant,spec,plantspec);
02865 //plantspec.Write("tmp_plantspec.gen");
02866 plantspec.ClearStateNames();
02867 // plantspec.DotWrite("tmp_plantspec");
02868  FD_DF("Size of plantspec: "<<plantspec.Size()<<" - Statemin...");
02869 //string anykey;
02870 //getline(cin,anykey);
02871 StateMin(plantspec,plantspecMin);
02872  FD_DF("done. New Statesize: "<<plantspecMin.Size()<<".");
02873 plantspec=plantspecMin;
02874 plantspecMin.Clear();
02875 plantspec.ClearStateNames();
02876  FD_DF("******************** computing YcAcyclic(plantspec):");
02877 
02878 // calculate YcAcyclic sublanguage of plantspec:
02879 Generator yclifeplantspec;
02880 YcAcyclic(plantspec,yc,yclifeplantspec);
02881 Generator yclifeplantspecMin;
02882 //cout <<endl<< "                     StateMin(yclifeplantspec)..."  << endl;
02883 //StateMin(yclifeplantspec,yclifeplantspecMin);
02884 //cout<<endl<<"Statesize of yclifeplantspec after StateMin (tmp_YcAcyclic_Min.gen): "<<yclifeplantspecMin.Size();
02885 yclifeplantspecMin=yclifeplantspec;
02886 yclifeplantspecMin.ClearStateNames();
02887 //yclifeplantspecMin.Write("tmp_YcAcyclic_Min.gen");
02888 
02889  FD_DF("******************** actual spec: composition yclifeplantspec||minhio||locconstr (tmp_actualspec.gen)");
02890 //generate plantspec with closed-loop I/O sorting:
02891 Parallel(yclifeplantspecMin,minhio,plantspec);
02892 
02893 //add local constraints to plantspec: the result is the actual spec for synthesis
02894 Generator actualspec;
02895 Parallel(plantspec,locconstr,actualspec);
02896 //actualspec.Write("tmp_actualspec.gen");
02897 
02898  FD_DF("******************** closed loop synthesis: tmp_closedloop.gen/.dot");
02899 
02900 //std::cout<<"Starting NormalCompleteSynth....";
02901 FD_DF("Starting NormalCompleteSynth....");
02902 
02903 // compute normal, complete and controllable sublangugae of actualspec w.r.t. plant under constraints (cplant):
02904 Generator loop;
02905  NormalCompleteSynth(hiocplant,controllable,yc+uc+yp+up,actualspec,loop);
02906 //loop.Write("tmp_closedloop.gen");
02907 //loop.DotWrite("tmp_closedloop");
02908 
02909  FD_DF("size of closed loop before StateMin: "<<loop.Size()<<", starting StateMin...");
02910  
02911 //std::cout<<"Starting NormalCompleteSynth....done... starting StateMin";
02912 FD_DF("Starting NormalCompleteSynth....done... starting StateMin");
02913  
02914 Generator minloop;
02915 StateMin(loop,minloop);
02916  FD_DF("...size of closed loop after StateMin (tmp_closedloop.gen): "<<minloop.Size());
02917 //minloop=loop;
02918 minloop.ClearStateNames();
02919 //minloop.Write("tmp_closedloop.gen");
02920 // test: recheck for YCless SCCs:
02921 Generator minlooptest;
02922 minlooptest=minloop;
02923  std::set<StateSet> SccSet;
02924 YclessScc(minlooptest,yc,SccSet);
02925  FD_DF("");
02926  FD_DF("*********number of Yc-less strongly connencted components in closed loop (should be zero): "
02927        <<SccSet.size());
02928 
02929 // minloop.DotWrite("tmp_minclosedloop");
02930 
02931 //calculate external closedloop:
02932  FD_DF("******************** external closed loop: tmp_extloop.gen/.dot");
02933 Generator extloop;
02934 Project(minloop,sigmace,extloop);
02935  FD_DF("size of external closed loop: "<<extloop.Size());;
02936 
02937 // recheck if specification is met:
02938 if(LanguageInclusion(extloop,rSpec)) {
02939   FD_DF("External closed loop meets specification.");
02940     }
02941 if(LanguageEquality(extloop,rSpec)) {
02942   FD_DF("External closed loop EQUALS specification.");
02943     }
02944 
02945 extloop.ClearStateNames();
02946 //extloop.Write("tmp_extloop.gen");
02947 //extloop.DotWrite("tmp_extloop");
02948 
02949  FD_DF("******************** project closed loop: tmp_controller.gen/.dot ");
02950 
02951 Generator controller;
02952 Project(minloop,sigmacp,controller);
02953 controller.ClearStateNames();
02954 //controller.Write("tmp_controller.gen");
02955 // controller.DotWrite("tmp_controller");
02956 
02957  FD_DF("******************** extend to IO controller: tmp_IOcontroller.gen/.dot ");
02958 
02959 // extend to io-controller
02960 Generator HioController, minIOcontroller;
02961  HioFreeInput(controller, yp, up, HioController, "errUp","errYp");
02962 //HioController.Write("tmp_IOcontroller.gen");
02963 // HioController.DotWrite("tmp_IOcontroller");
02964  FD_DF("size of IO controller: "<<HioController.Size()<<", StateMin...");
02965 StateMin(HioController,minIOcontroller);
02966  FD_DF("...size of IO controller after StateMin: "<<minIOcontroller.Size());
02967 minIOcontroller.ClearStateNames();
02968 //minIOcontroller.Write("tmp_IOcontroller.gen");
02969 
02970 // RESULT:
02971 rController = minIOcontroller;
02972 
02973 ////*******************************************************************
02974 // // uncomment this, if you use complete_synth, instead of
02975 // // normal_complete_synth, for controller design:
02976 
02977 //cout <<endl<< "******************** checking normality... "  << endl;
02978 //
02979 //if(!isnormal(minloop,hiocplant,sigmacp))
02980 //    {
02981 //    cout<<endl<<"isnormal says: false! :("<<endl;
02982 //    }
02983 //else
02984 //    {
02985 //    cout<<endl<<"isnormal says: true! :)"<<endl;
02986 //    }
02987 ////*******************************************************************
02988 
02989  FD_DF("IO controller synthesis done. ******************** " );
02990 }
02991 
02992 }//namespace faudes

libFAUDES 2.18b --- 2010-12-17 --- c++ source docu by doxygen 1.6.3