op_observercomputation.cpp

Go to the documentation of this file.
00001 
00013 /* FAU Discrete Event Systems Library (libfaudes)
00014 
00015    Copyright (C) 2006  Bernd Opitz
00016    Exclusive copyright is granted to Klaus Schmidt
00017 
00018    This library is free software; you can redistribute it and/or
00019    modify it under the terms of the GNU Lesser General Public
00020    License as published by the Free Software Foundation; either
00021    version 2.1 of the License, or (at your option) any later version.
00022 
00023    This library is distributed in the hope that it will be useful,
00024    but WITHOUT ANY WARRANTY; without even the implied warranty of
00025    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026    Lesser General Public License for more details.
00027 
00028    You should have received a copy of the GNU Lesser General Public
00029    License along with this library; if not, write to the Free Software
00030    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00031 
00032 #include "op_observercomputation.h"
00033   
00034 namespace faudes{
00035 
00036 // calcAbstAlphObs(rGenObs, rHighAlph, rNewHighAlph, rMapRelabeledEvents)
00037 void calcAbstAlphObs(cGenerator& rGenObs, EventSet& rHighAlph, EventSet& rNewHighAlph, map<Idx,set<Idx > > &  rMapRelabeledEvents) {
00038   OP_DF("calcAbstAlphObs(" << rGenObs.Name() << "," << "rHighAlph, rNewHighAlph, rMapRelabeledEvents)");
00039   // The controllable events are separated from the cGenerator. All functions that are successively 
00040   // called, are defined for vGenerators
00041   EventSet cntrevs = rGenObs.ControllableEvents();
00042   calcAbstAlphObs(rGenObs, cntrevs , rHighAlph, rNewHighAlph, rMapRelabeledEvents);
00043   // the controllable events that have been changed by the called function are set in the cGenerator cGenObs
00044   rGenObs.SetControllable(cntrevs);
00045 }
00046 
00047 // calcAbstAlphObs(rGenObs, rControllableEvents, rHighAlph, rNewHighAlph, rMapRelabeledEvents)
00048 void calcAbstAlphObs(vGenerator& rGenObs, EventSet& rControllableEvents, EventSet& rHighAlph, EventSet& rNewHighAlph, map<Idx,set<Idx > > &  rMapRelabeledEvents) {
00049   OP_DF("calcAbstAlphObs(" << rGenObs.Name() << "," << "rControllableEvents, rHighAlph, rNewHighAlph, rMapRelabeledEvents)");
00050   // The function called next returns a relabeled generator and a map of relabeled transitions
00051   map<Transition,Idx>  changedtrans;
00052   calcAbstAlphObs(rGenObs, rControllableEvents, rHighAlph, rNewHighAlph, changedtrans);
00053   // for later use, the relabeled transitions are converted into relabeled events 
00054   // note that this function is accumulative, i.e., rMapRelabeledEvents need not be empty
00055   map<Transition,Idx>::iterator rtEndIt = changedtrans.end();
00056   map<Transition,Idx>::iterator rtIt =  changedtrans.begin();
00057   for(; rtIt != rtEndIt; rtIt++){
00058     if(rMapRelabeledEvents.find(rtIt->first.Ev) == rMapRelabeledEvents.end() ){// if the event does not exist, yet, a nex element in the map is created
00059       rMapRelabeledEvents[rtIt->first.Ev] = set<Idx>();
00060       if(rGenObs.Alphabet().Exists(rtIt->second) )// FIXME: there seem to be relabeled transitions that do not exist 
00061         rMapRelabeledEvents[rtIt->first.Ev].insert(rtIt->second);
00062     } 
00063     else {  // a new label is inserted into the map
00064       if(rGenObs.Alphabet().Exists(rtIt->second) )// FIXME: there seem to be relabeled transitions that do not exist    
00065         rMapRelabeledEvents[rtIt->first.Ev].insert(rtIt->second);
00066     }
00067   }
00068 }
00069 
00070 // calcAbstAlphObs(rGenObs, rControllableEvents, rHighAlph, rNewHighAlph, rMapChangedTrans)
00071 void calcAbstAlphObs(vGenerator& rGenObs, EventSet& rControllableEvents, EventSet& rHighAlph, EventSet& rNewHighAlph, map<Transition,Idx>& rMapChangedTrans)
00072 { 
00073   OP_DF("calcAbstAlphObs(" << rGenObs.Name() << ", rControllableEvents, rHighAlph, rNewHighAlph, rMapChangedTRans)");
00074   // Initialization of variables
00075   rNewHighAlph = rHighAlph;
00076   rMapChangedTrans.clear();
00077   Generator genDyn(rGenObs);
00078   map<Transition,Transition> mapChangedTransReverse;
00079   vector<Idx> newPartitions;
00080   map<Idx,Idx> mapStateToPartition;
00081   map<Idx, EventSet> mapRelabeledEvents;
00082   bool done=false;
00083   #ifdef DF_PLOT
00084     Idx iterationCount=1;
00085     string name;
00086   #endif
00087   // observer algorithm: In each step, a dynamic system is computed that fulfills the one-step observer condition. 
00088   // Iterative application of the bisimulation algorithm and the relabeling procedure yields an automaton rGenObs
00089   // that, together with the new high-level alphabet rNewHighAlph fulfills the observer condition. 
00090   while(done==false)
00091   {
00092     // compute dynamic system for Lm-observer on rGenObs
00093     calculateDynamicSystemObs(rGenObs, rNewHighAlph, genDyn);
00094     #ifdef DF_PLOT
00095     name = ("./Automata/Plots/" + rGenObs.Name() + "DynamicSystem_" + ToString(iterationCount));
00096     genDyn.DotWrite(name);
00097     #endif
00098   
00099     Generator genPart;
00100     mapStateToPartition.clear();
00101     newPartitions.clear();
00102   
00103     // compute coarsest quasi-congruence on the dynamic system
00104     calcBisimulation(genDyn, mapStateToPartition, genPart, newPartitions);
00105     #ifdef DF_PLOT
00106     name = ("./Automata/Plots/" + rGenObs.Name() + "Bisimulation_" + ToString(iterationCount));
00107     genPart.DotWrite(name);
00108     ++iterationCount;
00109     #endif
00110   
00111     // check if quotient automaton is deterministic and free of unobservable events
00112     // and relabel transitions in rGenObs if necessary. The high-level alphabet is modified accordingly
00113     done=relabel(rGenObs, rControllableEvents, rNewHighAlph, newPartitions, mapStateToPartition, mapChangedTransReverse,  rMapChangedTrans, mapRelabeledEvents);
00114   }
00115 }
00116 
00117 // calculateDynamicSystemObs(rGen, rHighAlph, rGenDyn)
00118 void calculateDynamicSystemObs(const vGenerator& rGen, EventSet& rHighAlph, vGenerator& rGenDyn)
00119 {
00120   OP_DF("calculateDynamicSystemObs(" << rGen.Name() << "," << rHighAlph.Name() << "," << rGenDyn.Name() << ")");
00121   // transition relation sorted in reverse order for backwards reachability
00122   TransSetX2EvX1 tset_X2EvX1;
00123   rGen.TransRel(tset_X2EvX1);
00124   
00125   // prepare generator rGenDyn
00126   rGenDyn.ClearTransRel();
00127   rGenDyn.InjectAlphabet(rHighAlph); // all high-level events are contained in the alphabet of rGenDyn
00128   
00129   // helpers
00130   EventSet::Iterator eIt = rGenDyn.AlphabetBegin();
00131   EventSet::Iterator eItEnd = rGenDyn.AlphabetEnd();
00132   
00133   TransSetX2EvX1::Iterator tItByX2Ev;
00134   TransSetX2EvX1::Iterator tItByX2EvEnd;
00135   StateSet reach;
00136   StateSet::Iterator sIt;
00137   StateSet::Iterator sItEnd;
00138   TransSet::Iterator tIt;
00139   TransSet::Iterator tItEnd;
00140   map<Idx,StateSet> entryStateToLocalReach;
00141   set<Idx>::iterator esIt, esItEnd;
00142   // map that maps a state (first Idx) to a reachable entry state (second Idx) via a high-level event (third Idx)
00143   map<Idx,vector<pair<Idx,Idx> > > stateToEntryState;
00144   map<Idx,vector<pair<Idx,Idx> > >::iterator stesIt;
00145   map<Idx,vector<pair<Idx,Idx> > >::iterator stesItEnd;
00146   // label for transitions to marked states in the dynamic system
00147   std::string eventname = ( rGenDyn.EventSymbolTablep())->UniqueSymbol("mLabel_1");
00148   Idx mLabel = (rGenDyn.EventSymbolTablep())->InsEntry(eventname);
00149   
00150   // algorithm for computing the dynamic system
00151   
00152   // loop over all states of original generator
00153   StateSet::Iterator stateSetIt = rGen.StatesBegin();
00154   StateSet::Iterator stateSetItEnd = rGen.StatesEnd();
00155   for( ; stateSetIt != stateSetItEnd; ++stateSetIt) {
00156     OP_DF("calculateDynamicSystemObs: loop over all states; current state: " << rGen.StateName(*stateSetIt) 
00157     << " [" << *stateSetIt << "]");
00158     
00159     // compute locally reachable states for current state
00160     reach.Clear();
00161     LocalAccessibleReach(rGen, rHighAlph, *stateSetIt, reach);
00162     OP_DF("calculateDynamicSystemObs: states in local reach: \n " << reach.ToString() );
00163     
00164     // check if current state (*stateSetIt) is an entry-state (a backward transition with
00165     // a high-level event exists. If yes, the locally reachable states (reach) are stored in
00166     // the entryStateToLocalReach map
00167     tItByX2Ev=tset_X2EvX1.BeginByX2(*stateSetIt); 
00168     tItByX2EvEnd=tset_X2EvX1.EndByX2(*stateSetIt); 
00169     for(; tItByX2Ev != tItByX2EvEnd; ++tItByX2Ev)
00170     {
00171       OP_DF("calculateDynamicSystemObs: checking transition : " << rGen.TStr(*tItByX2Ev));
00172       if(rHighAlph.Exists(tItByX2Ev->Ev)){
00173           OP_DF("calculateDynamicSystemObs: current state is an entry-state");
00174           // map entry-state to its locally reachable states
00175           entryStateToLocalReach[*stateSetIt]=reach;
00176           break;
00177       }
00178     }
00179     vector<pair<Idx,Idx> > emptyVector;
00180     stateToEntryState[*stateSetIt]=emptyVector;
00181     // loop over all states in the local reach of current state to determine which marked states
00182     // are locally reachable and to determine which high-level events can occur after local strings
00183     sIt=reach.Begin();
00184     sItEnd=reach.End();
00185     for( ; sIt != sItEnd; ++sIt) 
00186     {
00187       // check if state sIt is marked; if yes, create an m-transition (mLabel) between current state and sIt
00188       if(rGen.ExistsMarkedState(*sIt))
00189       {
00190           OP_DF("calculateDynamicSystemObs: marked state " << rGen.SStr(*sIt) 
00191           <<  " is locally reachable from current state");
00192           rGenDyn.InsEvent(mLabel); // ??
00193           rGenDyn.InsState(*stateSetIt); // ??
00194           rGenDyn.InsState(*sIt); //??
00195           rGenDyn.SetTransition(*stateSetIt, mLabel, *sIt);
00196       }
00197       // loop over all transitions of current state sIt to determine if high-level events are possible
00198       tIt    = rGen.TransRelBegin(*sIt);
00199       tItEnd = rGen.TransRelEnd(*sIt);
00200       for(; tIt != tItEnd; ++tIt)
00201       {
00202           OP_DF("calculateDynamicSystemObs: Loop over all states in reach; checking transition: " 
00203             << rGen.TStr(*tIt));
00204           if(rHighAlph.Exists(tIt->Ev))
00205           {
00206             OP_DF("calculateDynamicSystemObs: state " << rGen.SStr(tIt->X2) << 
00207             " is an entry state and can be reached from current state" << rGen.SStr(*stateSetIt) << " by event " << rGen.EventName(tIt->Ev));
00208             pair<Idx,Idx> newPair;
00209             newPair.first=tIt->X2;
00210             newPair.second=tIt->Ev;
00211             // store the reachable entry state and the corresponding high-level event
00212             stateToEntryState[*stateSetIt].push_back(newPair);
00213           }
00214       }
00215     }
00216   }
00217   
00218   // create the transition structure of the dynamic system
00219   stesIt    = stateToEntryState.begin();
00220   stesItEnd = stateToEntryState.end();
00221   vector<pair <Idx,Idx> >* pPairs;
00222   vector<pair <Idx,Idx> >::iterator vIt;
00223   vector<pair <Idx,Idx> >::iterator vItEnd;
00224   // To construct the dynamic system, each local state has to be connected to all states in
00225   // the local accessible reach of entry states that can be reached via a high-level event.
00226   // This information is contained in the stateToEntryState map combined with the entryStateToLocalReach map.
00227   // iteration over all entries (X1) of map stateToEntryState
00228   for(; stesIt != stesItEnd; ++stesIt)
00229   {
00230       pPairs=&(stesIt->second);
00231       vIt    = (*pPairs).begin();
00232       vItEnd = (*pPairs).end();
00233       // loop over all pairs (Ev,X2) of current entry
00234       for( ; vIt != vItEnd; ++vIt)
00235       {
00236         // check if transition already exists
00237         if(!((rGenDyn.TransRel()).Exists(stesIt->first,vIt->second,vIt->first))) 
00238         {
00239             // find local reach of entry state X2 
00240             StateSet* pLocalReach = &((entryStateToLocalReach.find(vIt->first))->second);
00241           
00242             // Add a Ev-transition from X1 to every state in the local reach of X2     
00243             StateSet::Iterator lrsIt    = pLocalReach->Begin();
00244             StateSet::Iterator lrsItEnd = pLocalReach->End();
00245             for(; lrsIt != lrsItEnd; ++lrsIt)
00246             {
00247               rGenDyn.InsEvent(vIt->second); // ??
00248               rGenDyn.InsState(stesIt->first); // ??
00249               rGenDyn.InsState(*lrsIt); //??
00250               rGenDyn.SetTransition(stesIt->first,vIt->second,*lrsIt);
00251               OP_DF("calculateDynamicSystemObs: Transition added to resulting generator: " << 
00252                 rGenDyn.TStr(Transition(stesIt->first,vIt->second,*lrsIt))); 
00253             }
00254         }
00255       }
00256   }
00257   OP_DF("calculateDynamicSystemObs: leaving function");
00258 }
00259 
00260 // calcAbstAlphObsOCC(rGenObs, rHighAlph, rNewHighAlph, rMapRelabeledEvents)
00261 void calcAbstAlphObsOCC(cGenerator& rGenObs, EventSet& rHighAlph, EventSet& rNewHighAlph, map<Idx,set<Idx > > &  rMapRelabeledEvents){
00262   OP_DF("calcAbstAlphObsOCC(" << rGenObs.Name() << "," << "rHighAlph, rNewHighAlph, rMapRelabeledEvents)");
00263   // The controllable events are separated from the cGenerator. All functions that are successively 
00264   // called, are defined for vGenerators
00265     map<Transition,Idx>  changedtrans;
00266     EventSet rControllableEvents = rGenObs.ControllableEvents();
00267     // The function called next returns a relabeled generator and a map of relabeled transitions
00268     calcAbstAlphObsOCC(rGenObs, rControllableEvents, rHighAlph, rNewHighAlph, changedtrans);
00269     // for later use, the relabeled transitions are converted into relabeled events 
00270   // note that this function is accumulative, i.e., rMapRelabeledEvents need not be empty
00271     map<Transition,Idx>::iterator rtEndIt = changedtrans.end();
00272     map<Transition,Idx>::iterator rtIt =  changedtrans.begin();
00273     for(; rtIt != rtEndIt; rtIt++){
00274         if(rMapRelabeledEvents.find(rtIt->first.Ev) == rMapRelabeledEvents.end() ){
00275            rMapRelabeledEvents[rtIt->first.Ev] = set<Idx>();
00276            if(rGenObs.Alphabet().Exists(rtIt->second) )// FIXME: there seem to be relabeled transitions that do not exist 
00277                rMapRelabeledEvents[rtIt->first.Ev].insert(rtIt->second);
00278         } else {  
00279            if(rGenObs.Alphabet().Exists(rtIt->second) )// FIXME: there seem to be relabeled transitions that do not exist    
00280                rMapRelabeledEvents[rtIt->first.Ev].insert(rtIt->second);
00281         }
00282     } 
00283     // the controllable events that have been changed by the called function are set in the cGenerator cGenObs
00284     rGenObs.SetControllable(rControllableEvents);
00285 }
00286 
00287 // calcAbstAlphObsOCC(rGenObs, rControllableEvents, rHighAlph, rNewHighAlph, rMapChangedTrans)
00288 void calcAbstAlphObsOCC(vGenerator& rGenObs, EventSet& rControllableEvents, EventSet& rHighAlph, EventSet& rNewHighAlph, map<Transition,Idx>& rMapChangedTrans)
00289 {
00290     OP_DF("calcAbstAlphObsOCC(" << rGenObs.Name() << ", rControllableEvents, rHighAlph, rNewHighAlph, rMapChangedTRans)");
00291   // Initialization of variables
00292     rNewHighAlph = rHighAlph;
00293     rMapChangedTrans.clear();
00294     Generator genDyn(rGenObs);
00295     map<Transition,Transition> mapChangedTransReverse;
00296     vector<Idx> newPartitions;
00297     map<Idx,Idx> mapStateToPartition;
00298     map<Idx, EventSet> mapRelabeledEvents;
00299     bool done=false;
00300     #ifdef DF_PLOT
00301         Idx iterationCount=1;
00302         string name;
00303     #endif   
00304     // observer algorithm: In each step, a dynamic system is computed that fulfills the one-step observer condition
00305     // and output control consistency (OCC). 
00306   // Iterative application of the bisimulation algorithm and the relabeling procedure yields an automaton rGenObs
00307   // that, together with the new high-level alphabet rNewHighAlph fulfills the observer condition and OCC.
00308     while(done==false)
00309     {
00310         // compute dynamic system for Lm-observer and OCC on rGenObs
00311         calculateDynamicSystemObsOCC(rGenObs, rControllableEvents, rNewHighAlph, genDyn);
00312         #ifdef DF_PLOT
00313             name = ("./Automata/Plots/" + rGenObs.Name() + "DynamicSystem_" + ToString(iterationCount));
00314             genDyn.DotWrite(name);
00315         #endif
00316 
00317         Generator genPart;
00318         mapStateToPartition.clear();
00319         newPartitions.clear();
00320         // compute coarsest quasi-congruence on the dynamic system
00321         calcBisimulation(genDyn, mapStateToPartition, genPart, newPartitions);
00322         #ifdef DF_PLOT
00323             name = ("./Automata/Plots/" + rGenObs.Name() + "Bisimulation_" + ToString(iterationCount));
00324             genPart.DotWrite(name);
00325             ++iterationCount;
00326         #endif
00327     
00328         // check if quotient automaton is deterministic and free of unobservable events
00329     // and relabel transitions in rGenObs if necessary. The high-level alphabet is modified accordingly
00330         done=relabel(rGenObs, rControllableEvents, rNewHighAlph, newPartitions, mapStateToPartition, mapChangedTransReverse,  rMapChangedTrans, mapRelabeledEvents);
00331     }
00332 }
00333 
00334 // calculateDynamicSystemObsOCC(rGen, rControllableEvents, rHighAlph, rGenDyn)
00335 void calculateDynamicSystemObsOCC(const vGenerator& rGen, EventSet& rControllableEvents, EventSet& rHighAlph, vGenerator& rGenDyn){
00336     OP_DF("calculateDynamicSystemObsOCC(" << rGen.Name() << "," << rControllableEvents.Name() << "," << rHighAlph.Name() << "," << rGenDyn.Name() << ")");
00337   // transition relation sorted in reverse order for backwards reachability
00338     TransSetX2EvX1 tset_X2EvX1;
00339     rGen.TransRel(tset_X2EvX1);
00340 
00341   // prepare generator rGenDyn
00342   rGenDyn.ClearTransRel();
00343   rGenDyn.InjectAlphabet(rHighAlph); // all high-level events are contained in the alphabet of rGenDyn
00344   // labels for transitions to marked states and for controllable paths
00345   std::string eventname = ( rGenDyn.EventSymbolTablep())->UniqueSymbol("cLabel_1");
00346   Idx cLabel = (rGenDyn.EventSymbolTablep())->InsEntry(eventname);
00347   eventname = ( rGenDyn.EventSymbolTablep())->UniqueSymbol("mLabel_1");
00348   Idx mLabel = (rGenDyn.EventSymbolTablep())->InsEntry(eventname);
00349   rGenDyn.InsEvent(cLabel);
00350   rGenDyn.InsEvent(mLabel);
00351   rGenDyn.InjectInitStates(rGen.InitStates() );
00352   rGenDyn.InjectStates(rGen.States() );
00353   rGenDyn.InjectMarkedStates(rGen.MarkedStates() );
00354 
00355   // maps for the construction of the dynamic system
00356   map<Idx, map<Idx, bool> > exitLocalStatesMap; // map from each exit state to locally backward reachable states and a boolean that is false if there exists an uncontrollable path to the exit state
00357   map<Idx, StateSet> entryLocalStatesMap; // map from entry states to locally forward reachable states
00358   StateSet::Iterator stIt, stEndIt;
00359   stIt = rGen.StatesBegin();
00360   stEndIt = rGen.StatesEnd();
00361   TransSet::Iterator tsIt, tsEndIt;
00362   bool isExitState;
00363   // go through all states of the original generator
00364   for(; stIt != stEndIt; stIt++){
00365       OP_DF("calculateDynamicSystemObsOCC: loop over all states; current state: " << rGen.StateName(*stIt) 
00366     << " [" << *stIt << "]");
00367     // determine the marked states that are locally reachable from the current state and insert 
00368     // transitions labeled with mLabel in rGenDyn
00369     forwardReachabilityObs(rGen, rHighAlph, *stIt, mLabel, rGenDyn);
00370     // if the current state is an exit state, carry out the backward reachability to determine 
00371     // which states can be reached on a controllable/uncontrollable path -> store in exitLocalStatesMap
00372     // in this case, also determine the corresponding entry states and compute their locally reachable states
00373     // for the entryLocalStatesMap
00374     tsIt = rGen.TransRelBegin(*stIt);
00375     tsEndIt = rGen.TransRelEnd(*stIt);
00376     isExitState = false;
00377     for( ; tsIt != tsEndIt; tsIt++){
00378       if(rHighAlph.Exists(tsIt->Ev) ){
00379                    OP_DF("calculateDynamicSystemObsOCC: current state is an exit-state");
00380         isExitState = true;
00381         // if the local reach for the connected entry state has not been computed, yet, insert it in the 
00382         // entryLocalStatesMap
00383         if( entryLocalStatesMap.find(tsIt->X2) == entryLocalStatesMap.end() ){
00384           entryLocalStatesMap[tsIt->X2] = StateSet();
00385           LocalAccessibleReach(rGen,rHighAlph, tsIt->X2, entryLocalStatesMap[tsIt->X2]);
00386         }
00387       }
00388     }
00389     // if the current state is an exit state, compute the backward local reach with the controllability properties of the 
00390     // paths to locally backward reachable states
00391     if(isExitState == true){
00392       StateSet doneStates;
00393       exitLocalStatesMap[*stIt][*stIt] = false; // the exit state is reachable from the exit state via an uncontrollable path
00394       doneStates.Insert(*stIt);
00395       backwardReachabilityObsOCC(tset_X2EvX1, rControllableEvents, rHighAlph, *stIt, *stIt, false, exitLocalStatesMap, doneStates);
00396       
00397     }
00398     
00399   }
00400   // the generator rGenDyn is constructed by connecting all exit and entry states with their local state sets
00401   map<Idx, map<Idx, bool> >::const_iterator elIt, elEndIt;
00402   elIt = exitLocalStatesMap.begin();
00403   elEndIt = exitLocalStatesMap.end();
00404   map<Idx,bool>::const_iterator lcIt, lcEndIt;
00405   StateSet::Iterator exIt, exEndIt;
00406   map<Idx,StateSet>::const_iterator enIt;
00407 
00408   for( ; elIt != elEndIt; elIt++){
00409     lcEndIt = elIt->second.end();
00410     // go over all entry states reachable from the current exit state (via all feasible high-level events)
00411     tsIt = rGen.TransRel().Begin(elIt->first);
00412     tsEndIt = rGen.TransRel().End(elIt->first);
00413     for( ; tsIt != tsEndIt; tsIt++){
00414         OP_DF("calculateDynamicSystemObsOCC: insert transitions for the high-level event" << rGen.EventName(tsIt->Ev) << "[" << tsIt->Ev << "]");
00415       if(rHighAlph.Exists(tsIt->Ev) ){
00416         bool controllable = rControllableEvents.Exists(tsIt->Ev);
00417         enIt = entryLocalStatesMap.find(tsIt->X2);
00418         stEndIt = enIt->second.End();
00419         // iterate over all locally backward reachable states from current exit state
00420         for(lcIt = elIt->second.begin(); lcIt != lcEndIt; lcIt ++){
00421           // iterate over all locally forward reachable states from current entry state
00422           for( stIt = enIt->second.Begin(); stIt != stEndIt; stIt++){
00423               OP_DF("calculateDynamicSystemObsOCC: Transition added to resulting generator: " << 
00424                 rGenDyn.TStr(Transition(lcIt->first,tsIt->Ev,*stIt))); 
00425             
00426                         rGenDyn.SetTransition(lcIt->first,tsIt->Ev,*stIt); // insert a transition for each local state combination
00427                         if( controllable || lcIt->second ){ // insert an clabel transition if the local path is controllable or the high-level event is controllable
00428                             OP_DF("calculateDynamicSystemObsOCC: cLabel-Transition added to resulting generator: " << 
00429                             rGenDyn.TStr(Transition(lcIt->first,cLabel,*stIt))); 
00430                             
00431                             rGenDyn.SetTransition(lcIt->first,cLabel,*stIt);
00432                         }
00433           }
00434         }
00435       }
00436     }   
00437   }
00438 }
00439 
00440 // forwardReachabilityObs(rGen, rHighAlph, lowState, mLabel, rGenDyn)
00441 void forwardReachabilityObs(const vGenerator& rGen, const EventSet& rHighAlph, Idx lowState, Idx mLabel, vGenerator& rGenDyn) {
00442   OP_DF("forwardReachabilityObs(" << rGen.Name() << "," << rHighAlph.Name() << "," << lowState << "," << rGenDyn.EventName(mLabel) << "," << rGenDyn.Name() << ")");
00443     // helpers:
00444   // iterators
00445   TransSet::Iterator tIt;
00446   TransSet::Iterator tEndIt;
00447   // todo list
00448   std::stack<Idx> todo;
00449 
00450   // algorithm: the locally reachable states from lowState are evaluated. If a reachable state is marked,
00451   // a transition with mLabel is inserted from lowState to that state is inserted in rGenDyn. 
00452   todo.push(lowState);
00453   StateSet doneStates;
00454   // if lowState is marked itself, the dynamic system contains a selfloop with the mlabel
00455   if(rGen.MarkedStates().Exists(lowState) ){
00456       OP_DF("forwardReachabilityObs: Transition with mLabel added to resulting generator: " << 
00457                 rGenDyn.TStr(Transition(lowState,mLabel,lowState)));
00458     rGenDyn.SetTransition(lowState, mLabel, lowState);
00459   }
00460 
00461   doneStates.Insert(lowState);
00462   // the local reachability is evaluated until no new state is found
00463   while (! todo.empty()) {
00464     const Idx current = todo.top();
00465     todo.pop();
00466     tIt = rGen.TransRelBegin(current);
00467     tEndIt = rGen.TransRelEnd(current);
00468     for (; tIt != tEndIt; ++tIt) {
00469       // if the current transition is labeled with a high level event, it is skipped
00470       if (rHighAlph.Exists(tIt->Ev)) {
00471         continue;
00472       }
00473       // if the successor state has not been found, yst (not in doneStates)
00474       else if (! doneStates.Exists(tIt->X2)) {
00475         todo.push(tIt->X2);
00476         if(rGen.MarkedStates().Exists(tIt->X2) ){
00477             OP_DF("forwardReachabilityObs: Transition with mLabel added to resulting generator: " << 
00478                 rGenDyn.TStr(Transition(lowState,mLabel,tIt->X2)));
00479           rGenDyn.SetTransition(lowState, mLabel, tIt->X2);
00480         }
00481         doneStates.Insert(tIt->X2);
00482       }
00483     }
00484   }
00485 }
00486 
00487 // backwardReachabilityObsOCC(rTransSetX2EvX1, rControllableEvents, rHighAlph, exitState, currentState, controllablePath, rExitLocalStatesMap, rDoneStates) 
00488 void backwardReachabilityObsOCC(const TransSetX2EvX1& rTransSetX2EvX1, const EventSet& rControllableEvents, const EventSet& rHighAlph, Idx exitState, Idx currentState, bool controllablePath, map<Idx, map<Idx, bool> >& rExitLocalStatesMap, StateSet& rDoneStates){
00489   OP_DF("backwardReachabilityObsOCC(rTransSetX2EvX1," << rControllableEvents.Name() << "," << rHighAlph.Name() << "," << exitState << "," << currentState << "," << controllablePath << ",rExitLocalStatesMap, rDoneStates)");
00490     // go along all backward transitions. Discard the goal state if it is reached via a high-level event or if it is in the rDoneStates and 
00491     // the controllability properties of the state do not change on the current path
00492     
00493     // helpers
00494   TransSetX2EvX1::Iterator tsIt, tsEndIt;
00495     tsIt = rTransSetX2EvX1.BeginByX2(currentState);
00496     tsEndIt = rTransSetX2EvX1.EndByX2(currentState);
00497   bool currentControllablePath;
00498   // we iterate over all backward transitions of the currentState to establish backward reachability
00499   for( ;tsIt != tsEndIt; tsIt++){
00500       // states reachable via a high-level event are not in the local backward reach and the controllability property of the current exitState does not change
00501     if( !rHighAlph.Exists(tsIt->Ev) && tsIt->X1 != exitState){
00502       // if the state has not been visited, yet, the controllability of the current path are set in the rExitLocalStatesMap
00503                 if( !rDoneStates.Exists(tsIt->X1) ){
00504         rDoneStates.Insert(tsIt->X1);
00505         // the path is controllable if the current transition has a controllable event or the path was already controllable
00506         currentControllablePath = rControllableEvents.Exists(tsIt->Ev) || controllablePath;
00507         rExitLocalStatesMap[exitState][tsIt->X1] = currentControllablePath;
00508         // as the state has not been visited, yet, it is subject to a new backward reachability
00509         backwardReachabilityObsOCC(rTransSetX2EvX1, rControllableEvents, rHighAlph, exitState, tsIt->X1, currentControllablePath, rExitLocalStatesMap, rDoneStates);
00510       }
00511       else{ // for an existing state, the controllability value can change from uncontrollable to controllable (if 
00512         // a new controllable path has been found). It is important to note, that the OCC condition implies that
00513         // if there is one controllable path, then the the state is flagged controllable except for the case of the 
00514         // given exitState that is always uncontrollable
00515         currentControllablePath = rControllableEvents.Exists(tsIt->Ev) || controllablePath;
00516         if(rExitLocalStatesMap[exitState][tsIt->X1] != currentControllablePath && currentControllablePath == true){
00517           rExitLocalStatesMap[exitState][tsIt->X1] = true;
00518           // as the controllabiity attribute of the current state changed it is subject to a new backward reachability
00519           backwardReachabilityObsOCC(rTransSetX2EvX1, rControllableEvents, rHighAlph, exitState, tsIt->X1, true, rExitLocalStatesMap, rDoneStates);
00520         }
00521       }
00522     }
00523   }
00524 }
00525 
00526 // calcAbstAlphObsLCC(rGenObs, rHighAlph, rNewHighAlph, rMapRelabeledEvents)
00527 void calcAbstAlphObsLCC(cGenerator& rGenObs, EventSet& rHighAlph, EventSet& rNewHighAlph, map<Idx,set<Idx > > &  rMapRelabeledEvents){
00528     OP_DF("calcAbstAlphObsLCC(" << rGenObs.Name() << "," << "rHighAlph, rNewHighAlph, rMapRelabeledEvents)");
00529     // The controllable events are separated from the cGenerator. All functions that are successively 
00530     // called, are defined for vGenerators
00531     map<Transition,Idx>  changedtrans;
00532     EventSet rControllableEvents = rGenObs.ControllableEvents();
00533     // The function called next returns a relabeled generator and a map of relabeled transitions
00534     calcAbstAlphObsLCC(rGenObs, rControllableEvents, rHighAlph, rNewHighAlph, changedtrans);
00535     // for later use, the relabeled transitions are converted into relabeled events 
00536   // note that this function is accumulative, i.e., rMapRelabeledEvents need not be empty
00537     map<Transition,Idx>::iterator rtEndIt = changedtrans.end();
00538     map<Transition,Idx>::iterator rtIt =  changedtrans.begin();
00539     for(; rtIt != rtEndIt; rtIt++){
00540     if(rMapRelabeledEvents.find(rtIt->first.Ev) == rMapRelabeledEvents.end() ){
00541        rMapRelabeledEvents[rtIt->first.Ev] = set<Idx>();
00542        if(rGenObs.Alphabet().Exists(rtIt->second) )
00543            rMapRelabeledEvents[rtIt->first.Ev].insert(rtIt->second);
00544     } else {  
00545        if(rGenObs.Alphabet().Exists(rtIt->second) )
00546            rMapRelabeledEvents[rtIt->first.Ev].insert(rtIt->second);
00547     }
00548       } 
00549       // the controllable events that have been changed by the called function are set in the cGenerator cGenObs
00550       rGenObs.SetControllable(rControllableEvents);
00551 }
00552 
00553 // calcAbstAlphObsLCC(rGenObs, rControllableEvents, rHighAlph, rNewHighAlph, rMapChangedTrans)
00554 void calcAbstAlphObsLCC(vGenerator& rGenObs, EventSet& rControllableEvents, EventSet& rHighAlph, EventSet& rNewHighAlph, map<Transition,Idx>& rMapChangedTrans)
00555 {
00556     OP_DF("calcAbstAlphObsLCC(" << rGenObs.Name() << ", rControllableEvents, rHighAlph, rNewHighAlph, rMapChangedTRans)");
00557   // Initialization of variables
00558     rNewHighAlph = rHighAlph;
00559     rMapChangedTrans.clear();
00560     Generator genDyn(rGenObs);
00561     map<Transition,Transition> mapChangedTransReverse;
00562     vector<Idx> newPartitions;
00563     map<Idx,Idx> mapStateToPartition;
00564     map<Idx, EventSet> mapRelabeledEvents;
00565     bool done=false;
00566     #ifdef DF_PLOT
00567         Idx iterationCount=1;
00568         string name;
00569     #endif   
00570     // observer algorithm: In each step, a dynamic system is computed that fulfills the one-step observer condition
00571     // and local control consistency (LCC). 
00572   // Iterative application of the bisimulation algorithm and the relabeling procedure yields an automaton rGenObs
00573   // that, together with the new high-level alphabet rNewHighAlph fulfills the observer condition and LCC.
00574     while(done==false)
00575     {
00576          // compute dynamic system for Lm-observer and OCC on rGenObs
00577          calculateDynamicSystemObsLCC(rGenObs, rControllableEvents, rNewHighAlph, genDyn);
00578         #ifdef DF_PLOT
00579             name = ("./Automata/Plots/" + rGenObs.Name() + "DynamicSystem_" + ToString(iterationCount));
00580             genDyn.DotWrite(name);
00581         #endif
00582 
00583         Generator genPart;
00584         mapStateToPartition.clear();
00585         newPartitions.clear();
00586         // compute coarsest quasi-congruence on the dynamic system
00587         calcBisimulation(genDyn, mapStateToPartition, genPart, newPartitions);
00588         #ifdef DF_PLOT
00589             name = ("./Automata/Plots/" + rGenObs.Name() + "Bisimulation_" + ToString(iterationCount));
00590             genPart.DotWrite(name);
00591             ++iterationCount;
00592         #endif
00593     
00594         // check if quotient automaton is deterministic and free of unobservable events
00595     // and relabel transitions in rGenObs if necessary. The high-level alphabet is modified accordingly
00596         done=relabel(rGenObs, rControllableEvents, rNewHighAlph, newPartitions, mapStateToPartition, mapChangedTransReverse,  rMapChangedTrans, mapRelabeledEvents);
00597     }
00598 }
00599 
00600 // calculateDynamicSystemObsLCC(rGen, rControllableEvents, rHighAlph, rGenDyn)
00601 void calculateDynamicSystemObsLCC(const vGenerator& rGen, EventSet& rControllableEvents, EventSet& rHighAlph, vGenerator& rGenDyn){
00602     OP_DF("calculateDynamicSystemObsLCC(" << rGen.Name() << "," << rControllableEvents.Name() << "," << rHighAlph.Name() << "," << rGenDyn.Name() << ")");
00603   // transition relation sorted in reverse order for backwards reachability
00604     TransSetX2EvX1 tset_X2EvX1;
00605     rGen.TransRel(tset_X2EvX1);
00606 
00607     // prepare generator rGenDyn
00608     rGenDyn.ClearTransRel();
00609     rGenDyn.InjectAlphabet(rHighAlph);
00610   std::string eventname = ( rGenDyn.EventSymbolTablep())->UniqueSymbol("ucLabel_1");
00611   Idx ucLabel = (rGenDyn.EventSymbolTablep())->InsEntry(eventname);
00612   eventname = ( rGenDyn.EventSymbolTablep())->UniqueSymbol("mLabel_1");
00613   Idx mLabel = (rGenDyn.EventSymbolTablep())->InsEntry(eventname);
00614   rGenDyn.InsEvent(ucLabel);
00615   rGenDyn.InsEvent(mLabel);
00616   rGenDyn.InjectInitStates(rGen.InitStates() );
00617   rGenDyn.InjectStates(rGen.States() );
00618   rGenDyn.InjectMarkedStates(rGen.MarkedStates() );
00619 
00620   // maps for the construction of the dynamic system
00621   map<Idx, map<Idx, bool> > exitLocalStatesMap; // map from each exit state to locally backward reachable states and a boolean that is false if there exists an uncontrollable path to the exit state
00622   map<Idx, StateSet> entryLocalStatesMap; // map from entry states to locally forward reachable states
00623   StateSet::Iterator stIt, stEndIt;
00624   stIt = rGen.StatesBegin();
00625   stEndIt = rGen.StatesEnd();
00626   TransSet::Iterator tsIt, tsEndIt;
00627   bool isExitState;
00628   // go through all states of the original generator
00629   for(; stIt != stEndIt; stIt++){
00630     OP_DF("calculateDynamicSystemObsLCC: loop over all states; current state: " << rGen.StateName(*stIt) 
00631     << " [" << *stIt << "]");
00632     // determine the marked states that are locally reachable from the current state and insert 
00633     // transitions labeled with mLabel in rGenDyn
00634     forwardReachabilityObs(rGen, rHighAlph, *stIt, mLabel, rGenDyn);
00635     // if the current state is an exit state, carry out the backward reachability to determine 
00636     // which states can be reached on a controllable/uncontrollable path -> store in exitLocalStatesMap
00637     // in this case, also determine the corresponding entry states and compute their locally reachable states
00638     // for the entryLocalStatesMap
00639     tsIt = rGen.TransRelBegin(*stIt);
00640     tsEndIt = rGen.TransRelEnd(*stIt);
00641     isExitState = false;
00642     for( ; tsIt != tsEndIt; tsIt++){
00643       if(rHighAlph.Exists(tsIt->Ev) ){
00644           OP_DF("calculateDynamicSystemObsLCC: current state is an exit-state");
00645         isExitState = true;
00646         // if the local reach for the connected entry state has not been computed, yet, insert it in the 
00647         // entryLocalStatesMap
00648         if( entryLocalStatesMap.find(tsIt->X2) == entryLocalStatesMap.end() ){
00649           entryLocalStatesMap[tsIt->X2] = StateSet();
00650           LocalAccessibleReach(rGen,rHighAlph, tsIt->X2, entryLocalStatesMap[tsIt->X2]);
00651         }
00652       }
00653     }
00654     // if the current state is an exit state, compute the backward local reach with the controllability properties of the 
00655     // paths to locally backward reachable states
00656     if(isExitState == true){
00657       StateSet doneStates;
00658       exitLocalStatesMap[*stIt][*stIt] = false; // the exit state is reachable from the exit state via an uncontrollable path
00659       doneStates.Insert(*stIt);
00660       backwardReachabilityObsLCC(tset_X2EvX1, rControllableEvents, rHighAlph, *stIt, *stIt, false, exitLocalStatesMap, doneStates);
00661       
00662     }
00663     
00664   }
00665   // the generator rGenDyn is constructed by connecting all exit and entry states with their local state sets
00666   map<Idx, map<Idx, bool> >::const_iterator elIt, elEndIt;
00667   elIt = exitLocalStatesMap.begin();
00668   elEndIt = exitLocalStatesMap.end();
00669   map<Idx,bool>::const_iterator lcIt, lcEndIt;
00670   StateSet::Iterator exIt, exEndIt;
00671   map<Idx,StateSet>::const_iterator enIt;
00672 
00673   for( ; elIt != elEndIt; elIt++){
00674     lcEndIt = elIt->second.end();
00675     // go over all entry states reachable from the current exit state (via all feasible high-level events)
00676     tsIt = rGen.TransRel().Begin(elIt->first);
00677     tsEndIt = rGen.TransRel().End(elIt->first);
00678     for( ; tsIt != tsEndIt; tsIt++){
00679         OP_DF("calculateDynamicSystemObsLCC: insert transitions for the high-level event" << rGen.EventName(tsIt->Ev) << "[" << tsIt->Ev << "]");
00680       if(rHighAlph.Exists(tsIt->Ev) ){
00681         bool controllable = rControllableEvents.Exists(tsIt->Ev);
00682         enIt = entryLocalStatesMap.find(tsIt->X2);
00683         stEndIt = enIt->second.End();
00684         // iterate over all locally backward reachable states from current exit state
00685         for(lcIt = elIt->second.begin(); lcIt != lcEndIt; lcIt ++){
00686           // iterate over all locally forward reachable states from current entry state
00687           for( stIt = enIt->second.Begin(); stIt != stEndIt; stIt++){
00688             OP_DF("calculateDynamicSystemObsLCC: Transition added to resulting generator: " << 
00689                   rGenDyn.TStr(Transition(lcIt->first,tsIt->Ev,*stIt))); 
00690                 
00691                               rGenDyn.SetTransition(lcIt->first,tsIt->Ev,*stIt); // insert a transition for each local state combination
00692             if( !(controllable || lcIt->second) ){ // insert an uclabel transition if the local path is uncontrollable
00693               OP_DF("calculateDynamicSystemObsLCC: cLabel-Transition added to resulting generator: " << 
00694                                     rGenDyn.TStr(Transition(lcIt->first,ucLabel,*stIt))); 
00695 
00696                                     rGenDyn.SetTransition(lcIt->first,ucLabel,*stIt);
00697             }
00698           }
00699         }
00700       }   
00701     }
00702   }
00703 }
00704 
00705 // backwardReachabilityObsLCC(crTransSetX2EvX1, rControllableEvents, rHighAlph, exitState, currentState, controllablePath, rExitLocalStatesMap, rDoneStates)
00706 void backwardReachabilityObsLCC(const TransSetX2EvX1& rTransSetX2EvX1, const EventSet& rControllableEvents, const EventSet& rHighAlph, Idx exitState, Idx currentState, bool controllablePath, map<Idx, map<Idx, bool> >& rExitLocalStatesMap, StateSet& rDoneStates){
00707   OP_DF("backwardReachabilityObsOCC(rTransSetX2EvX1," << rControllableEvents.Name() << "," << rHighAlph.Name() << "," << exitState << "," << currentState << "," << controllablePath << ",rExitLocalStatesMap, rDoneStates)");
00708     // go along all backward transitions. Discard the goal state if it is reached via a high-level event or if it is in the rDoneStates and 
00709     // the controllability properties of the state do not change on the current path
00710     
00711     // helpers
00712   TransSetX2EvX1::Iterator tsIt, tsEndIt;
00713     tsIt = rTransSetX2EvX1.BeginByX2(currentState);
00714     tsEndIt = rTransSetX2EvX1.EndByX2(currentState);
00715   bool currentControllablePath;
00716   // we iterate over all backward transitions of the currentState to establish backward reachability
00717   for( ;tsIt != tsEndIt; tsIt++){
00718       // states reachable via a high-level event are not in the local backward reach and the controllability property of the current exitState does not change
00719     if( !rHighAlph.Exists(tsIt->Ev) && tsIt->X1 != exitState){
00720       // if the state has not been visited, yet, the controllability of the current path are set in the rExitLocalStatesMap
00721            if( !rDoneStates.Exists(tsIt->X1) ){
00722         rDoneStates.Insert(tsIt->X1);
00723         // the path is uncontrollable if the current transition has an uncontrollable event or the path was already uncontrollable
00724         currentControllablePath = rControllableEvents.Exists(tsIt->Ev) || controllablePath;
00725         rExitLocalStatesMap[exitState][tsIt->X1] = currentControllablePath;
00726         // as the state has not been visited, yet, it is subject to a new backward reachability
00727                 backwardReachabilityObsLCC(rTransSetX2EvX1, rControllableEvents, rHighAlph, exitState, tsIt->X1, currentControllablePath, rExitLocalStatesMap, rDoneStates);
00728       }
00729       else{ // for an existing state, the controllability value can change from controllable to uncontrollable (if 
00730         // a new uncontrollable path has been found). It is important to note, that the LCC condition implies that
00731         // if there is one uncontrollable path, then the state is flagged uncontrollable except for the case of the 
00732         // given exitState that is always uncontrollable
00733         currentControllablePath = rControllableEvents.Exists(tsIt->Ev) || controllablePath;
00734         if(rExitLocalStatesMap[exitState][tsIt->X1] != currentControllablePath && currentControllablePath == false){
00735           rExitLocalStatesMap[exitState][tsIt->X1] = currentControllablePath;
00736           // as the controllabiity attribute of the current state changed it is subject to a new backward reachability
00737                     backwardReachabilityObsLCC(rTransSetX2EvX1, rControllableEvents, rHighAlph, exitState, tsIt->X1, false, rExitLocalStatesMap, rDoneStates);
00738         }
00739       }
00740     }
00741   }
00742 }
00743 
00744 // relabel(rGenRelabel, rControllableEvents, rHighAlph, rNewPartitions, rMapStateToPartition, rMapChangedTransReverse, rMapChangedTrans, rMapRelabeledEvents)
00745 bool relabel(vGenerator& rGenRelabel, EventSet& rControllableEvents, EventSet& rHighAlph, vector<Idx>& rNewPartitions, map<Idx,Idx>& rMapStateToPartition, map<Transition,Transition>& rMapChangedTransReverse, map<Transition,Idx>& rMapChangedTrans, map<Idx, EventSet>& rMapRelabeledEvents)
00746 {
00747 
00748     OP_DF("relabel(" << rGenRelabel.Name() << "," << rControllableEvents.Name() << "," << rHighAlph.Name() << ", rNewPartition, rMapStateToPartition, rMapChangedTransReverse, rMapChangedTrans, rMapRelabeledEvents)");
00749 
00750   // helpers
00751 
00752   // keep track of how transitions between cosets have been relabeled
00753   // first Idx: coset from where transition starts, second Idx: high-level event,
00754   // third Idx: other coset, where transition ends, forth Idx: new high-level event
00755   map<Idx, map<Idx, map<Idx, Idx> > > mapRelabel;
00756   
00757   // set of low-level events, that have not been relabeled
00758   set<Idx> notRelabeledLowEvents;
00759   // transition relation of the original version of rGenRelabel
00760   const TransSet& transSet = rGenRelabel.TransRel();  
00761   TransSet::Iterator tIt = transSet.Begin();
00762   TransSet::Iterator tItEnd = transSet.End();
00763   // vector that contains pairs of original and changed transitions
00764   vector<pair<TransSet::Iterator,Transition> > editTransSet;
00765   // prepare data structure for keeping track of how transitions were relabeled
00766   vector<Idx>::iterator newPartIt = rNewPartitions.begin();
00767   vector<Idx>::iterator newPartItEnd = rNewPartitions.end();
00768   for(; newPartIt != newPartItEnd; ++newPartIt)
00769     mapRelabel[*newPartIt]=map<Idx, map <Idx, Idx> >();
00770   
00771   // algorithm: The relabeling according to the state partition as computed by the bisimulation algorithm is
00772   // performed. A high-level transitions is relebaled with a new event, if a transition with the same event leads
00773   // from the same coset to a different coset (non-determinism in the projected automaton). A low-level transition
00774   // is relabeled if it connects different cosets (corresponds to unobservable transition betweeen cosets). The 
00775   // also has build-in procedures to take care that as few new event labels as possible are introduced. 
00776   
00777   // iteration over all transitions of rGenRelabel
00778   for(; tIt != tItEnd; ++tIt)
00779   {
00780     OP_DF("relabel: current transition: " << rGenRelabel.TStr(*tIt) );
00781     Idx indexX1Partition=rMapStateToPartition[tIt->X1];
00782     OP_DF("relabel: X1 belongs to coset with index " << indexX1Partition);
00783     Idx indexX2Partition=rMapStateToPartition[tIt->X2];
00784     OP_DF("relabel: X2 belongs to coset with index " << indexX2Partition);
00785   
00786     //check if current transition is labeled with a high-level-event
00787     if(rHighAlph.Exists(tIt->Ev))
00788     {
00789       OP_DF("relabel: Event is high-level event");
00790       // In the first case, there exists no entry for this transition in mapRelabel. Hence, this is the
00791       // first occurence of tIt->Ev leaving the coset of tIt->X1 found in the iteration.
00792       // Thus, there is no need to relabel this event. Store transition in mapRelabel
00793       if(mapRelabel[indexX1Partition].find(tIt->Ev) == mapRelabel[indexX1Partition].end())
00794       {
00795         mapRelabel[indexX1Partition][tIt->Ev][indexX2Partition]=tIt->Ev;
00796         OP_DF("relabel: First occurence of the current event leaving the current X1-coset");
00797       }
00798       // Otherwise, there exists an entry for the current event leaving the current X1-coset. It has to be
00799       // verified if the transition goes to the same coset as the previously found transitions or not.
00800       else 
00801       {
00802         // check if a transition with the same event has already been found that enters the same X2-coset. If
00803         // yes, the same label as for this transition is chosen. If not, a new label is introduced. 
00804         if(mapRelabel[indexX1Partition][tIt->Ev].find(indexX2Partition) != mapRelabel[indexX1Partition][tIt->Ev].end())
00805         {
00806           if(mapRelabel[indexX1Partition][tIt->Ev][indexX2Partition] != tIt->Ev)
00807           {
00808             OP_DF("relabel: the same event leading to the same X2-coset has already been relabeld before. The current transition is relabeld correspondingly");
00809             pair<TransSet::Iterator,Transition> newPair;
00810             newPair.first=tIt;
00811             newPair.second = Transition(tIt->X1,mapRelabel[indexX1Partition][tIt->Ev][indexX2Partition],tIt->X2);
00812             editTransSet.push_back(newPair);
00813           }
00814           else //nothing to be done
00815             OP_DF("relabel: There already exists a high-level transition from the current X1-coset to the same X2-coset and the current transition ist labeled with the same event. No relabeling necessary");
00816         }
00817         // there are entries of tIt->Ev, but no one leads to the same X2-coset. 
00818         // Check if new labels created before can be reused. If not, create a new one 
00819         // and eliminate the non-determinism by relebeling the current transition tIt with this event
00820         else 
00821         {
00822           bool createNewLabel = false;
00823           // check if the event already has been relabeled for some other transition
00824           if(rMapRelabeledEvents.find(tIt->Ev) != rMapRelabeledEvents.end())
00825           {
00826             EventSet::Iterator lsIt    = rMapRelabeledEvents[tIt->Ev].Begin();
00827             EventSet::Iterator lsItEnd = rMapRelabeledEvents[tIt->Ev].End();
00828             for(; lsIt != lsItEnd; ++lsIt)
00829             {
00830               createNewLabel = false;
00831               map<Idx,Idx>::iterator mapIt    = mapRelabel[indexX1Partition][tIt->Ev].begin();
00832               map<Idx,Idx>::iterator mapItEnd = mapRelabel[indexX1Partition][tIt->Ev].end();
00833               for(; mapIt != mapItEnd; ++mapIt)
00834               { 
00835                 // if the currently investigated label has already been used in 
00836                 // the current coset for a transition to another coset, relabeling is necessary
00837                 if(mapIt->second == *lsIt)
00838                 {
00839                   createNewLabel = true;
00840                   break;
00841                 }
00842               }
00843               // use an old label if possible
00844               if(createNewLabel == false)
00845               {
00846                 pair<TransSet::Iterator,Transition> newPair;
00847                 newPair.first=tIt;
00848                 newPair.second = Transition(tIt->X1,*lsIt,tIt->X2);
00849                 editTransSet.push_back(newPair);
00850                 OP_DF("relabel: An event was found that can be reused: " << rGenRelabel.EventName(*lsIt));
00851                 break;
00852               }
00853             }
00854           }
00855           // if no useable labels are available, a new label has to be introduced
00856           else
00857           {
00858             createNewLabel = true;
00859           }
00860           // no label could be found that can be reused
00861           if(createNewLabel == true)
00862           {
00863             // create a new label and relabel the current transition with it
00864             std::string eventName = ( rGenRelabel.EventSymbolTablep())->UniqueSymbol(rGenRelabel.EventSymbolTablep()->Symbol(tIt->Ev) + "newHLevent_1");
00865             Idx newLabel = (rGenRelabel.EventSymbolTablep())->InsEntry(eventName);
00866         
00867             rGenRelabel.InsEvent(eventName);
00868             // if the original is controllable, the attribute of the new event is also controllable
00869             if(rControllableEvents.Exists(tIt->Ev)){ 
00870               rControllableEvents.Insert(newLabel);
00871             }
00872             OP_DF("relabel: No event that can be reused could be found. The new event " << rGenRelabel.EventName(newLabel) << " was created");
00873             rHighAlph.Insert(newLabel);
00874             //create the new transition and remember that the old one has to be replaced with the new one
00875             pair<TransSet::Iterator,Transition> newPair;
00876             newPair.first=tIt;
00877             newPair.second = Transition(tIt->X1,newLabel,tIt->X2);
00878             editTransSet.push_back(newPair);
00879             rMapRelabeledEvents[tIt->Ev].Insert(newLabel);
00880           }
00881         }
00882       }
00883     }
00884     // the current transition is labeled with a low-level event
00885     else
00886     {
00887       OP_DF("relabel: Event is low-level event");
00888       // potential relabeling is only necessary if the low-level transition leaves its coset
00889       if(indexX1Partition != indexX2Partition)
00890       {
00891         // transition connects two cosets and it is the first occurrence of the event. 
00892         // Create a new event and relabel the transition with it                                
00893         if(rMapRelabeledEvents.find(tIt->Ev) == rMapRelabeledEvents.end())
00894         {
00895           std::string eventName = ( rGenRelabel.EventSymbolTablep())->UniqueSymbol(rGenRelabel.EventSymbolTablep()->Symbol(tIt->Ev) + "newHLevent_1");
00896           Idx newLabel = (rGenRelabel.EventSymbolTablep())->InsEntry(eventName);
00897           rGenRelabel.InsEvent(eventName);
00898           // insert the new event in the high-level alphabet and set its controllability property
00899           rHighAlph.Insert(newLabel);
00900           if(rControllableEvents.Exists(tIt->Ev)){ 
00901           rControllableEvents.Insert(newLabel);
00902           }
00903           OP_DF("relabel: First occurence of current low-level event " << rGenRelabel.EventName(tIt->Ev) 
00904           << " between cosets. The new event " << rGenRelabel.EventName(newLabel) << " was created");
00905           mapRelabel[indexX1Partition][tIt->Ev][indexX2Partition]=newLabel;
00906           rMapRelabeledEvents[tIt->Ev].Insert(newLabel);
00907           pair<TransSet::Iterator,Transition> newPair;
00908           newPair.first=tIt;
00909           newPair.second  = Transition(tIt->X1,newLabel,tIt->X2);
00910           editTransSet.push_back(newPair);
00911         }
00912         // there are entries of tIt->Ev, but no one leads to the same X2-coset. 
00913         // Check if new labels created before can be reused. If not, create a new one 
00914         // and eliminate the non-determinism by relebeling the current transition tIt with this event
00915         else 
00916         {
00917           EventSet::Iterator lsIt    = rMapRelabeledEvents[tIt->Ev].Begin();
00918           EventSet::Iterator lsItEnd = rMapRelabeledEvents[tIt->Ev].End();
00919           bool createNewLabel = true;
00920           for(; lsIt != lsItEnd; ++lsIt)
00921           {
00922             bool labelFound = false;
00923             // check if the event already has been relabeled for some other transition
00924             if(mapRelabel.find(indexX1Partition) == mapRelabel.end())
00925             {
00926               // if the currently investigated label has already been used in 
00927               // the current coset for a transition to another coset, relabeling is necessary
00928               labelFound = true;
00929             }
00930             else
00931             {
00932               // label lsIt can be reused as this is the first low-level transition leaving the X1-coset
00933               if(mapRelabel[indexX1Partition].find(tIt->Ev) == mapRelabel[indexX1Partition].end())
00934               {
00935                 labelFound = true;
00936               }
00937               else
00938               {
00939                 // a transition with the same original event tIt->Ev leaving the X1-coset has been found before
00940                 // and it entered a different X2-coset. Check if one of them was relabeled with lsIt. If yes, then lsIt can
00941                 // not be reused and the next event has to be examined. If no, lsIt can be reused 
00942                 if(mapRelabel[indexX1Partition][tIt->Ev].find(indexX2Partition) == mapRelabel[indexX1Partition][tIt->Ev].end())
00943                 {
00944                   map<Idx,Idx>::iterator mapIt=mapRelabel[indexX1Partition][tIt->Ev].begin();
00945                   map<Idx,Idx>::iterator mapItEnd=mapRelabel[indexX1Partition][tIt->Ev].end();
00946                   labelFound = true;
00947                   for(; mapIt != mapItEnd; ++ mapIt)
00948                   {
00949                     if(mapIt->second== *lsIt)
00950                     {
00951                       labelFound = false;
00952                       break;
00953                     }
00954                   }
00955                 } 
00956                 // a transition with the same original event tIt-Ev leaving the X1-coset has been found before
00957                 // and it entered the same X2-coset. Reuse the corresponding label
00958                 else
00959                 {
00960                   pair<TransSet::Iterator,Transition> newPair;
00961                   newPair.first=tIt;
00962                   newPair.second = Transition(tIt->X1,mapRelabel[indexX1Partition][tIt->Ev][indexX2Partition],tIt->X2);
00963                   editTransSet.push_back(newPair);
00964                   OP_DF("relabel: A transition to same X2-coset has already been found and relabeled before; the current transition is also labeled with " << rGenRelabel.EventName(mapRelabel[indexX1Partition][tIt->Ev][indexX2Partition]));
00965                   createNewLabel = false;
00966                   break;
00967                 }
00968               }
00969             }
00970             // reuse existing event
00971             if(labelFound == true)
00972             {
00973               pair<TransSet::Iterator,Transition> newPair;
00974               newPair.first=tIt;
00975               newPair.second = Transition(tIt->X1,*lsIt,tIt->X2);
00976               editTransSet.push_back(newPair);
00977               OP_DF("relabele: Low level event "  << rGenRelabel.EventName(tIt->Ev) << " is relabeled with " << rGenRelabel.EventName(*lsIt) << " which can be reused");
00978               mapRelabel[indexX1Partition][tIt->Ev][indexX2Partition]=*lsIt;
00979               createNewLabel = false;
00980               break;
00981             }
00982           } //end for
00983           // a new label has to be created and the corresponding transition is inserted
00984           if(createNewLabel == true)
00985           {
00986             std::string eventName = ( rGenRelabel.EventSymbolTablep())->UniqueSymbol(rGenRelabel.EventSymbolTablep()->Symbol(tIt->Ev) + "newHLevent_1"); //??
00987             Idx newLabel = (rGenRelabel.EventSymbolTablep())->InsEntry(eventName);
00988             rGenRelabel.InsEvent(eventName);
00989             // insert the new event in the high-level alphabet and set its controllability property
00990             rHighAlph.Insert(newLabel);
00991             if(rControllableEvents.Exists(tIt->Ev) ){ 
00992               rControllableEvents.Insert(newLabel);
00993             }
00994             OP_DF("relabel: No label could be reused, and the new event " << rGenRelabel.EventName(newLabel) << " was created");
00995             mapRelabel[indexX1Partition][tIt->Ev][indexX2Partition]=newLabel;
00996             pair<TransSet::Iterator,Transition> newPair;
00997             newPair.first=tIt;
00998             newPair.second = Transition(tIt->X1,newLabel,tIt->X2);
00999             editTransSet.push_back(newPair);
01000             rMapRelabeledEvents[tIt->Ev].Insert(newLabel);
01001           }
01002         }
01003       }
01004       // the low-level event does not have to be relabeled 
01005       else //indexX1Partition==indexX2Partition
01006       {
01007         notRelabeledLowEvents.insert(tIt->Ev);
01008       }
01009     }
01010   }
01011     
01012     
01013   // It is possible that events need not be relabeled. For example, if all occurrences of a low-level event have to 
01014   // be relabeled and added to the high-level alphabet, it is possible to just add the original low-level event
01015   // to the high-level alphabet without any relabeling. Note that this information is only available after all 
01016   // transitions have been evaluated.
01017   vector<pair<TransSet::Iterator,Transition> >::iterator etSetIt    = editTransSet.begin();
01018   vector<pair<TransSet::Iterator,Transition> >::iterator etSetItEnd = editTransSet.end();
01019   set<Idx> insertHighEvents;
01020   set<Idx> deleteHighEvents;
01021   bool quotAuotTrue=true;
01022   
01023   OP_DF("relabel: Trying to avoid unnecessariy new labels");
01024   // All relabeled transitions are checked
01025   for(etSetIt = editTransSet.begin(); etSetIt != editTransSet.end(); ++etSetIt)
01026   {
01027     Idx oldEvent = etSetIt->first->Ev;
01028     Idx newEvent = etSetIt->second.Ev;
01029     OP_DF("relabel: Checking transition X1="  << rGenRelabel.StateName(etSetIt->first->X1)<< " ["<<etSetIt->first->X1
01030     << "] Ev=" << rGenRelabel.EventName(oldEvent) << " X2="  << rGenRelabel.StateName(etSetIt->first->X2)
01031     << " [" << etSetIt->first->X2 << "] which shall be relabeled with event " << rGenRelabel.EventName(newEvent));
01032     // check if the original event is a low-level event and if there is an event left that has not been relabeled. If all events are relabeled, then at least one label can be replaced by the original event label.
01033     if(notRelabeledLowEvents.find(oldEvent) == notRelabeledLowEvents.end() && !rHighAlph.Exists(oldEvent))
01034     {
01035       OP_DF("relabel: There is no low-level event " << rGenRelabel.EventName(oldEvent) << " left");
01036       insertHighEvents.insert(oldEvent);
01037       // if a low-level event has been relabeled, the automaton under investigation is not the desired quotient automaton, yet.
01038       quotAuotTrue=false;
01039       // if newEvent is the first new event created for relabeling oldEvent, the relabeling is discarded
01040       if(rMapRelabeledEvents[oldEvent].Find(newEvent) == rMapRelabeledEvents[oldEvent].Begin())
01041       {
01042         OP_DF("relabel: Transition will not be relabeled");
01043         // if newEvent is the only event created for relabeling oldEvent, delete newEvent from rGenRelabel
01044         if(rMapRelabeledEvents[oldEvent].Find(newEvent)==(--(rMapRelabeledEvents[oldEvent].End())))
01045         {
01046           OP_DF("relabel: newEvent is the first and last event in rMapRelabeledEvents[oldEvent]");
01047           deleteHighEvents.insert(newEvent);
01048         }
01049         // delete pair<original Transition, new Transition>
01050         vector<pair<TransSet::Iterator,Transition> >::iterator helpIt = etSetIt;
01051         helpIt--;
01052         editTransSet.erase(etSetIt);
01053         etSetIt = helpIt;
01054       }
01055       else
01056       {
01057         // find predecessor of newEvent in map rMapRelabeledEvents[oldEvent] and use that event for relabeling
01058         Idx newLabel = *(--(rMapRelabeledEvents[oldEvent].Find(newEvent)));
01059         etSetIt->second.Ev = newLabel;
01060         // delete newEvent from rGenRelabel if it is no longer needed
01061         if(rMapRelabeledEvents[oldEvent].Find(newEvent)==(--(rMapRelabeledEvents[oldEvent].End())))
01062         {
01063           deleteHighEvents.insert(newEvent);
01064         }
01065       }
01066     }
01067   }
01068   // update the rMapRelabeledEvents with the changes
01069   // as the relabeling of oldEvent is discarded, it is removed from the map of relebeled events and
01070   // reinserted into the map of not relabeled events
01071 
01072   // mofidy alphabet of rGenRelabel and the abstraction alphabet by inserting the new high-level events and deleting the not needed new event labels.
01073   set<Idx>::iterator setIt    = insertHighEvents.begin();
01074   set<Idx>::iterator setItEnd = insertHighEvents.end();
01075   for(; setIt!= setItEnd; ++ setIt)
01076   {
01077     rHighAlph.Insert(*setIt);
01078   }
01079   setIt = deleteHighEvents.begin();
01080   setItEnd = deleteHighEvents.end();
01081   for(; setIt != setItEnd; ++setIt)
01082   {
01083     rGenRelabel.DelEvent(*setIt);
01084     rHighAlph.Erase(*setIt);
01085     rControllableEvents.Erase(*setIt); // controllable event is erased if it does not exist anymore. Schmidt 10/07
01086   }
01087     
01088   rControllableEvents = rControllableEvents * rGenRelabel.Alphabet(); // Schmidt 10/07
01089   // check if quotient automaton is deterministic and free of unobservable transitions, i.e., no transitions are relabeled and no low-level events are declared as high-level events
01090   if(editTransSet.empty()&& quotAuotTrue== true)
01091   {
01092     OP_DF("relabel: Leaving function relabel with true");
01093     return true; 
01094   }
01095     
01096   // delete original trnasitions and create relabeled transitions in rGenRelabel
01097   etSetIt = editTransSet.begin();
01098   etSetItEnd = editTransSet.end();
01099   for(; etSetIt != etSetItEnd; ++etSetIt)
01100   {
01101     map<Transition,Transition>::iterator mrIt;
01102     mrIt=rMapChangedTransReverse.find(*(etSetIt->first));
01103     // if the current relabeled transition has already been relabeled in a previous step of the observer algorithm, the original transition is found in the rMapChangedTransReverse map.
01104     if(mrIt!=rMapChangedTransReverse.end())
01105     {
01106       Transition originalTrans = mrIt->second;
01107       (rMapChangedTrans.find(originalTrans))->second = (etSetIt->second).Ev;
01108       rMapChangedTransReverse.erase(mrIt);
01109       rMapChangedTransReverse[etSetIt->second]=originalTrans;
01110       OP_DF("relabel: The transition X1= " << rGenRelabel.SStr((etSetIt->first)->X1) << " Ev=" << rGenRelabel.EStr((etSetIt->first)->Ev) << " X2= " << rGenRelabel.SStr((etSetIt->first)->X2) << " has already been relabeled in a former iteration step. The original transition was " << rGenRelabel.SStr(originalTrans.X1) << " Ev=" << rGenRelabel.EStr(originalTrans.Ev) << " X2= " << rGenRelabel.SStr(originalTrans.X2) << "; the new label is " << rGenRelabel.EStr((etSetIt->second).Ev));
01111     }
01112     // the current relabeled transition is simply inserted in the rMapChangedTrans map with its original transition if it is the first relabeling.
01113     else
01114     {
01115       rMapChangedTransReverse[etSetIt->second]=*(etSetIt->first);
01116       rMapChangedTrans[*(etSetIt->first)]=(etSetIt->second).Ev;
01117       OP_DF("relabel: First relabeling of transition X1=" << rGenRelabel.SStr((etSetIt->first)->X1) 
01118       << " Ev=" << rGenRelabel.EStr((etSetIt->first)->Ev) << " X2= " << rGenRelabel.SStr((etSetIt->first)->X2) << " new label is " << rGenRelabel.EStr((etSetIt->second).Ev));
01119     }
01120     // The old transition is removed and the new transition is inserted into rGenRelabel
01121     rGenRelabel.ClrTransition(etSetIt->first);
01122     rGenRelabel.SetTransition(etSetIt->second);
01123   }
01124   
01125   OP_DF("relabel: leaving function with false");
01126   return false;
01127 }
01128 
01129 // insertRelabeledEvents(rGenPlant, rMapRelabeledEvents, rNewEvents) 
01130 void insertRelabeledEvents(cGenerator& rGenPlant, const map<Idx,set<Idx> >&  rMapRelabeledEvents, cEventSet& rNewEvents) {
01131   map<Idx,set<Idx> >::const_iterator reEndIt = rMapRelabeledEvents.end();
01132   TransSet::Iterator tsEndIt = rGenPlant.TransRelEnd();
01133   TransSet::Iterator tsIt = rGenPlant.TransRelBegin();
01134   // check all transitions of rGenPlant
01135   for(; tsIt != tsEndIt; tsIt++){
01136     map<Idx,set<Idx> >::const_iterator reIt = rMapRelabeledEvents.find(tsIt->Ev);
01137     if(reIt == reEndIt) continue;
01138     const AttributeCFlags& attr = rGenPlant.EventAttribute(tsIt->Ev);
01139     set<Idx>::const_iterator rsEndIt = reIt->second.end();
01140     set<Idx>::const_iterator rsIt = reIt->second.begin();
01141     // if a transition with an event that gets new labels has been found, parallel transitions with the new 
01142     // events are added to rGenPlant
01143     for(; rsIt != rsEndIt; rsIt++){
01144       rGenPlant.InsEvent(*rsIt,attr);
01145       rNewEvents.Insert(*rsIt,attr);
01146       rGenPlant.SetTransition(tsIt->X1,*rsIt,tsIt->X2);
01147     }
01148   }
01149 }
01150 
01151 // insertRelabeledEvents(rGenPlant, rMapRelabeledEvents)
01152 void insertRelabeledEvents(cGenerator& rGenPlant, const map<Idx,set<Idx> >&  rMapRelabeledEvents) {
01153   map<Idx,set<Idx> >::const_iterator reEndIt = rMapRelabeledEvents.end();
01154   TransSet::Iterator tsEndIt = rGenPlant.TransRelEnd();
01155   TransSet::Iterator tsIt = rGenPlant.TransRelBegin();
01156   // check all transitions of rGenPlant
01157   for(; tsIt != tsEndIt; tsIt++){
01158     map<Idx,set<Idx> >::const_iterator reIt = rMapRelabeledEvents.find(tsIt->Ev);
01159     if(reIt == reEndIt) continue;
01160     const AttributeCFlags& attr = rGenPlant.EventAttribute(tsIt->Ev);
01161     set<Idx>::const_iterator rsEndIt = reIt->second.end();
01162     set<Idx>::const_iterator rsIt = reIt->second.begin();
01163     // if a transition with an event that gets new labels has been found, parallel transitions with the new 
01164     // events are added to rGenPlant
01165     for(; rsIt != rsEndIt; rsIt++){
01166       rGenPlant.InsEvent(*rsIt,attr);
01167       rGenPlant.SetTransition(tsIt->X1,*rsIt,tsIt->X2);
01168     }
01169   }
01170 }
01171  
01172 }

Generated on Fri May 9 11:26:47 2008 for libFAUDES 2.09b by  doxygen 1.4.4